C#控制台程序中,如何在不同类之间访问已定义的变量?
Hey there! Let's break down why you're seeing this behavior and how to fix it.
First off, the core issue here is that each class instance has its own independent Speed field. Your k is one instance of IgnitionKey, and s is a completely separate instance of GasBrake—they each store their own copy of the Speed value. Modifying k's Speed won't affect s's at all, and this has nothing to do with the ICar interface (the interface just defines a contract, each implementing class still maintains its own instance fields).
Here are a few practical solutions depending on your needs:
1. Use a static field for globally shared Speed
If you want all instances of IgnitionKey and its subclasses to share the same Speed value, declare Speed as a static field:
interface ICar { int Speed { get; set; } } class IgnitionKey : ICar { // Static field: shared across all instances private static int _speed; public int Speed { get => _speed; set => _speed = value; } public void Change() { Speed = 10; } } class GasBrake : IgnitionKey { } static void Main(string[] args) { IgnitionKey k = new IgnitionKey(); GasBrake s = new GasBrake(); k.Change(); Console.WriteLine(s.Speed); // Now outputs 10 Console.ReadLine(); }
⚠️ Note: Static variables are globally shared, so you'll need to add thread safety measures (like locks) if you're working in a multi-threaded environment to avoid data inconsistencies.
2. Extract shared state to a separate class (more flexible approach)
If you want to avoid global static variables (to prevent tight coupling and maintainability issues), move the Speed value into a dedicated state class, then have IgnitionKey and GasBrake instances reference the same state object:
// Class to hold shared car state class CarState { public int Speed { get; set; } } interface ICar { CarState State { get; } } class IgnitionKey : ICar { public CarState State { get; } // Inject the shared state via constructor public IgnitionKey(CarState state) { State = state; } public void Change() { State.Speed = 10; } } class GasBrake : IgnitionKey { // Pass the state to the parent constructor public GasBrake(CarState state) : base(state) {} } static void Main(string[] args) { // Create one shared state object CarState sharedState = new CarState(); IgnitionKey k = new IgnitionKey(sharedState); GasBrake s = new GasBrake(sharedState); k.Change(); Console.WriteLine(s.State.Speed); // Outputs 10 Console.ReadLine(); }
This approach is more flexible—you can assign different state objects to different groups of instances, avoiding the downsides of global state, and it's easier to test.
3. Singleton pattern (for a single global car instance)
If your business logic only needs one global car instance, design IgnitionKey as a singleton:
interface ICar { int Speed { get; set; } } class IgnitionKey : ICar { // Global singleton instance private static readonly IgnitionKey _instance = new IgnitionKey(); public static IgnitionKey Instance => _instance; public int Speed { get; set; } public void Change() { Speed = 10; } // Private constructor to block external instance creation private IgnitionKey() {} } class GasBrake : IgnitionKey { } static void Main(string[] args) { IgnitionKey k = IgnitionKey.Instance; // Note: This works only if GasBrake doesn't add unique logic beyond IgnitionKey GasBrake s = (GasBrake)IgnitionKey.Instance; k.Change(); Console.WriteLine(s.Speed); // Outputs 10 Console.ReadLine(); }
⚠️ Heads up: If GasBrake needs to add properties or methods that IgnitionKey doesn't have, the singleton pattern isn't a good fit—since the singleton can only be an IgnitionKey type instance.
内容的提问来源于stack exchange,提问作者PreS

