Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 458
daniel59 Avatar asked Mar 14 '23 04:03

daniel59


1 Answers

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.

like image 162
Dovydas Šopa Avatar answered Apr 24 '23 21:04

Dovydas Šopa