daniel59
daniel59

Reputation: 916

Inheritance of abstract class use another Type than defined for property

I created the following abstract class:

public abstract class AbstractClass
{
    public abstract string Name { get; set; }
    public abstract object Value { get; set; }
}

Now I want to derive two classes of the abstract class. I want to use an enum instead of the type object. My derived classes look like this:

First class:

public class InheritanceClass1:AbstractClass
{
    public override string Name { get; set; }
    public override FirstEnum Value { get; set; }
}

Second class:

public class InheritanceClass2 : AbstractClass
{
    public override string Name { get; set; }
    public override SecondEnum Value { get; set; }
}

I'm getting an error showed in my code, that the type of the property Value isn't object. I tryed to use the new-keyword instead of override like this:

In my abstract class:

public object Value { get; set; }

In my derived class:

public new FirstEnum Value { get; set; }

But if I create a List<AbstractClass> I have the problem that I can't use it for example for Linq because I would retrieve the "wrong" property. It is just hided, but still there, so I have to override the property.

So how do I have to change my abstract class and my derived classes, that I can use different types in my derived classes?

Upvotes: 5

Views: 1123

Answers (1)

Dovydas Šopa
Dovydas Šopa

Reputation: 2300

You can use abstract class like this:

public abstract class AbstractClass<T>
{
    public abstract string Name { get; set; }
    public abstract T Value { get; set; }
}

And derived class will change like this:

public class InheritanceClass1 : AbstractClass<FirstEnum>
{
    public override string Name { get; set; }
    public override FirstEnum Value { get; set; }
}

If you know that you will need only enums, you can add struct, IConvertible restriction to T:

public abstract class AbstractClass<T> where T : struct, IConvertible
{
    public abstract string Name { get; set; }
    public abstract T Value { get; set; }
}

Update based on comment:

Not the cleanest solution if you need List<AbstractClass>, but you can have additional class:

public abstract class AbstractClass
{
    public abstract string Name { get; set; }
    public abstract int GetValue ();
}

Which will then be inherited by AbstractClass<T>:

public abstract class AbstractClass<T> : AbstractClass where T : struct, IConvertible
{
    public abstract T Value { get; set; }
}

And InheritancClass:

public class InheritanceClass1 : AbstractClass<FirstEnum>
{
    public override string Name { get; set; }
    public override FirstEnum Value { get; set; }

    public override int GetValue () => (int)Value;
}

And then you can use it in a list:

var list = new List<AbstractClass> { new InheritanceClass1 (), new InheritanceClass2 () };

In this way you can use List<AbstractClass> with GetValue method. If you are using only enums you can always recast it to enum value. Ofcorse, you would not know exactly which enum it is, but you can add additional field for that.

Upvotes: 9

Related Questions