简体   繁体   中英

Virtual property of baseType

say I have 4 classes:

public class Class1{
    public virtual SubClass1 Subclass;
}

public class SubClass1 : SubClass{}

public class Class2 : Class1{
    public override SubClass2 Subclass;
}

public class SubClass2 : SubClass1{}

Is it possible to have a field or property where the type is dynamic without the type being the 'dynamic' type? So it can be overridde by a type that inherits from the initial virtual field/property?

Actual content

I'm making an RPG game with a public class of type 'Item' that have a private 'blueprint' field All items derive from this class or a subclass hereof, but the blueprint field that too is a base class that other blueprints derive from? So a sword is an item, with a sword blueprint that is a blueprint. How do I design this in a simple error-proff (not type dynamic) way?

You can use interfaces. What similarity (class members) would you like these 'dynamic' types to have? When you know the answer you can create an interface that defines these members and implement them on those classes. It would look similar to this:

public interface IItem {
    public IBlueprint Blueprint { get; set; }
}
public interface IBlueprint {
    public object Content { get; set; }
}

public class Blueprint1 : IBlueprint {
    public object Content { get => _content; set => _content = value; }

    private object _content;
    //Other stuff
}

public class Item1 : IItem{
    public IBluePrint Blueprint { get => _blueprint; set => _blueprint = value; }

    private string _blueprint;
    //Other stuff
}

Or otherwise you could use inheritance such that

public abstract class BaseItem {
    public BaseBlueprint Blueprint { get; set; }
}
public abstract class BaseBlueprint {
    public object Content { get; set; }
}

public class Blueprint1 : BaseBlueprint {
    //Included Content by default
    //Other stuff
}

public class Item1 : BaseItem{
    ///<summary>Constructor to initialize Blueprint</summary>
    public Item1() {
        BluePrint = new BluePrint1;
    }
}

The trick is to understand that by declaring a variable, the variable address stores the type data (signature) that is associated with the delaring type. So when you need to reference specific members not on the 'shared/dynamic' type, you will need to perform a cast to the exact object you want.

(I edited the answer to relate to the context, eg Item and Blueprint)

/// <summary>
/// Base class for all blueprint
/// </summary>
public abstract class BaseBlueprint
{
}

/// <summary>
/// Base class for items : all items inherit from this classe
/// </summary>
public abstract class BaseItem
{
    /// <summary>
    /// Now all items inherit this property
    /// </summary>
    protected BaseBlueprint blueprint;
}

public class SwordBlueprint : BaseBlueprint
{

}

public class Sword : BaseItem
{
    /// <summary>
    /// Constructor for a sword item
    /// </summary>
    public Sword()
    {
        //Since SwordBlueprint is a BaseBlueprint, you can assign it to the blueprint property
        this.blueprint = new SwordBlueprint();
    }
}

I made the BaseBlueprint and BaseItem abstract since they shouldn't be instanciated directly but only inherited. You can add virtual méthods inside to implement common actions (use, craft...) while having the possibility to override it for some items.

Polymorphism is often referred to as the third pillar of object-oriented programming. To implement the polymorphism is the only reason to create property (or method) that overrides an implementation of the base class. So the way you are trying to override doesn't make much sense, you can not gain anything if all overriden properties doesn't have the same signature but different implementation. In your case you should have different code inside of Get or/and Set for different classes, but not different signature.

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