简体   繁体   中英

Polymorphism issue - virtual fields? (C#)

I have problem with class design.

I have core class for my game objects. While drawing I need to retrieve position from the object. Unfortunately object is seen as it's base type so the position is not retrieved from derived class but from it's parent. Defining field as virtual would fix my problem, but it's impossible :(. How can I design class schema to avoid this problem?

Simple example of what's going on:

class BaseClass { public Vector2 position = new Vector2(){X=0,Y=0}; }
class Class:BaseClass { public new Vector2 position = new Vector2(){X=10,Y=10}; }

BaseClass c = new Class();
// c.position.X is now 0

You can rework this to use virtual properties instead of fields. This will handle things correctly.

If properties are not a possibility for whatever reason, you can also rework your constructor as follows:

class BaseClass
{
    public Vector2 position = new Vector2(){X=0,Y=0};
}

class Class:BaseClass 
{ 
    public Class()
    {
        this.position = new Vector2(){X=10,Y=10};
    }
}

This isn't exactly the same, since you aren't hiding the base class field with your own, but it will initialize it correctly so that you can use it as your example suggests.

  • The new keyword indicates to hide the symbol of the same name defined in the base class.
  • public fields are considered a "smell" in C#

Solution: use properties and override the property in the derived class:

class BaseClass {
    public virtual Vector2 Position {
        get { return new Vector2(){X=0,Y=0}; }
    }
}

class Class : BaseClass {
    public override Vector2 Position {
        get { return new Vector2(){X=10,Y=10}; }
    }
}

You can use a backing field to store the instances of Vector2 .

Alternatively, you can let the base class handle the position and just pass an initial value:

class BaseClass {
    private Vector2 _position;
    public BaseClass() {
        _position = new Vector2(){X=0,Y=0};
    }
    protected BaseClass(Vector2 initialPosition) {
        _position = initialPosition;
    }
    public Vector2 Position {
        get { return _position; }
        set { _position = value; }
    }
}

class Class : BaseClass {
    public Class() : base(new Vector2(){X=10,Y=10}) {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM