This is probably a silly question, but here it goes.Imagine you have the following classes:
public class C
{
}
public class D : C
{
//A subclass of C
}
public class A
{
C argument;
}
Now, I want to have a class B, that inherits from A.This class would obviously inherit the "argument" field, but I wish to force the "argument" field in B to be of type D, rather than C.Since D inherits from C this shouldn't create any problems. So, how would achieve this in c# ?
As Jared points out, this is not possible. However, it is interesting to consider why not.
Suppose the field is private. Then it cannot be accessed in derived class B. (Assuming B is not a nested type of A.)
Suppose the field is not private. Doesn't matter whether it is public, internal, protected or protected internal. Suppose its public and this were legal. Now you have the following situation.
class B : A
{
override public D argument; // "overrides" A.argument
}
class E : C { }
class F
{
public static void M(A a)
{ a.argument = new E(); }
}
...
F.M(new B());
And hey, you just crashed the runtime. You just wrote an object of type E into a field that can only store type D. (We could make similar crashing scenarios for other configurations, like protected fields, and so on.)
Now, you might say, well, instead let me make a read-only property. That I can virtualize:
class A
{
public virtual C Argument { get; }
}
class B : A
{
public override D Argument { ... }
}
Now the problems go away. The public interface isn't writable, so there's no problem with someone writing something in there that is not supported. And the property is virtual, so there's a mechanism for overriding it.
That feature is called "return type covariance", and it is not supported in C# either. See Why the concept of "Covariance" and "Contravariance" are applicable while implementing the methods of an interface?.
Please explain what you are really trying to do, not how you're trying to do it. There is probably a better way.
You could achieve something like so, where A is a generic type with its type parameter constrained to subclasses of C:-
public class C
{
}
public class D : C
{
}
public class A<T> where T:C
{
public T Argument { get; set; }
}
public class B : A<D>
{
}
Bear in mind that you shouldn't expose public (or protected) fields, which is why I've changed them to properties.
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