I have a subclass with an over-ridden method that I know always returns a particular subtype of the return type declared in the base class. If I write the code this way, it
Change your method signature on Derived class to:
public override BaseReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
C# doesn't support variant return types. You can check out this post for a way to do this using Generics...http://srtsolutions.com/blogs/billwagner/archive/2005/06/17/covaraint-return-types-in-c.aspx
Here's a sample using Generics in your model:
public class BaseReturnType
{
}
public class DerivedReturnType : BaseReturnType
{
}
public abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
public class DerviedClass : BaseClass<DerivedReturnType>
{
public override DerivedReturnType PolymorphicMethod()
{
throw new NotImplementedException();
}
}
It seems to me that you need to be returning an interface, not a base class.
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass {
public abstract BaseReturnType PolymorphicMethod();
}
class DerivedClass : BaseClass {
// Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override BaseReturnType PolymorphicMethod() {
return new DerivedReturnType();
}
}
this should work
You could make the class generic if that doesn't bothers you:
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass<T> where T : BaseReturnType
{
public abstract T PolymorphicMethod();
}
class DerivedClass : BaseClass<DerivedReturnType>
{
// Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod()
{
return new DerivedReturnType();
}
}
Generics are not necessarily the way to go. In particular, type(of Derived) is not considered a type(of Base).
First, add a new method to your derived class which will return the value with the correct type. Second, mark the overriding method not-overridable and have it delegate to your new method.
That's it. You've solved your problem. Child classes won't be able to re-expand the type because they must override your new method.
I apologize if the code isn't quite right; I'm used to VB.net.
abstract class C1 {
public abstract IEnumerable<Byte> F1();
}
class C2 : C1 {
public sealed override IEnumerable<Byte> F1() {
Return F2();
}
public overridable IList<Byte> F2() {
Return {1, 2, 3, 4};
}
}
You can do this if you introduce an extra method to override (since you can't override
and new
a method with the same name in the same type):
abstract class BaseClass
{
public BaseReturnType PolymorphicMethod()
{ return PolymorphicMethodCore();}
protected abstract BaseReturnType PolymorphicMethodCore();
}
class DerivedClass : BaseClass
{
protected override BaseReturnType PolymorphicMethodCore()
{ return PolymorphicMethod(); }
public new DerivedReturnType PolymorphicMethod()
{ return new DerivedReturnType(); }
}
Now you have a PolymorphicMethod
method at each level with the correct type.