I need a base class with a property where I can derive classes with the same property but different (compatible) types. The base Class can be abstract.
public class Base { public virtual object prop { get; set; } } public class StrBase : Base { public override string prop { get; set; } // compiler error } public class UseIt { public void use() { List<Base> l = new List<Base>(); //... } }
I tried it with Generics but that gives me a problem when using the class, because I want to store differently typed base classes in the List.
public class BaseG<T> { public T prop { get; set; } } public class UseIt { public void use() { List<BaseG> l = new List<BaseG>(); // requires type argument //... } }
You cannot "override" fields, because only methods can have overrides (and they are not allowed to be static or private for that). This trick lets A 's subclasses "push" a new value into the context of their superclass, getting the effect similar to "overriding" without an actual override.
In C# 8.0 and earlier, the return types of an override method and the overridden base method must be the same. You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method.
In C#, a method in a derived class can have the same name as a method in the base class. You can specify how the methods interact by using the new and override keywords. The override modifier extends the base class virtual method, and the new modifier hides an accessible base class method.
Here's an alternative approach to proposed solution:
public abstract class Base { public abstract void Use(); public abstract object GetProp(); } public abstract class GenericBase<T> : Base { public T Prop { get; set; } public override object GetProp() { return Prop; } } public class StrBase : GenericBase<string> { public override void Use() { Console.WriteLine("Using string: {0}", Prop); } } public class IntBase : GenericBase<int> { public override void Use() { Console.WriteLine("Using int: {0}", Prop); } }
Basically I've added a generic class in the middle that stores your properly-typed property. this will work assuming that you never need to access Prop
from the code that iterates the members of the List<Base>
. (You could always add an abstract method to Base
called GetProp
that casts the generic to an object if that's required.)
Sample usage:
class Program { static void Main(string[] args) { List<Base> l = new List<Base>(); l.Add(new StrBase {Prop = "foo"}); l.Add(new IntBase {Prop = 42}); Console.WriteLine("Using each item"); foreach (var o in l) { o.Use(); } Console.WriteLine("Done"); Console.ReadKey(); } }
Edit: Added the GetProp() method to illustrate how the property can be directly accessed from the base class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With