Unity中派生类与基类同名字段值同步问题咨询
Great question—this is a common gotcha with class inheritance in C# (and Unity specifically, thanks to serialization quirks!). Let's unpack why this happens and how to fix it.
Why the values don't sync right now
When you declare a field x in your DerivedClass that has the same name as x in BaseClass, you're not modifying or extending the base class's field—you're hiding it. These are two completely separate variables, stored in different parts of the object's memory. So when you set DerivedClass.x = 5, you're only updating that new, derived-specific field, while BaseClass.x remains at its default value of 0.
Unity makes this even trickier if you're serializing these fields (using [SerializeField]), because the editor will actually serialize both fields separately, leading to more confusion.
Fixes to sync the values
Here are two reliable approaches to make sure both the base and derived class use the same underlying value:
1. Share the base class field directly (simplest solution)
Instead of declaring a new x in the derived class, make the base class's x accessible to derived classes using the protected access modifier. This way, both classes are working with the exact same variable:
public class BaseClass : MonoBehaviour { protected int x = 0; // Protected lets derived classes read/write this field } public class DerivedClass : BaseClass { void Start() { x = 5; // This modifies the base class's x directly! } }
Now, calling player.GetComponent<BaseClass>().x will return 5, same as the derived class—because it's the same variable.
2. Use properties to enforce synchronization (if you need a "named member" in the derived class)
If for some reason you need to keep a member named x in the derived class (e.g., for interface compliance or code structure), use a property that wraps the base class's field. This ensures all accesses route to the base class's value:
public class BaseClass : MonoBehaviour { protected int _x = 0; // Backing field public virtual int x { get => _x; set => _x = value; } } public class DerivedClass : BaseClass { // Override the property instead of hiding it public override int x { get => base.x; // Delegate to base class's getter set => base.x = value; // Delegate to base class's setter } void Start() { x = 5; // Still modifies the base class's _x } }
This works because the derived property doesn't create a new variable—it just forwards all operations to the base class's property, keeping everything in sync.
Key takeaway
Never declare a field in a derived class that has the same name as a base class field unless you explicitly intend to hide it (and even then, use the new keyword to make your intent clear, like new int x;). For synchronization, always ensure both classes are operating on the same underlying variable—either by sharing the base class's field or using properties to redirect access.
内容的提问来源于stack exchange,提问作者Smaika

