I'm trying to neatly organize my code and came across and oddity as primarily Java-focused programmer. Here's the simplified version:
class ReturnParent { ... }
class ReturnChild : ReturnParent { ... }
class Parent
{
abstract ReturnParent SomeMethod();
}
class Child : Parent
{
// Note the return type
override ReturnChild SomeMethod() {}
}
Now I've looked up this issue and I know this doesn't work in C# because covariance isn't supported in this way. My question is, is there a workaround to this issue?
The method can be a parameter instead; the classes, including the return classes, MUST be classes, they cannot be interfaces; they can implement interfaces though, if that helps.
Also, the main class must be castable, which was an issue when I tried generics:
Parent p = new Child(); // This works
Child c = p as Child; // This doesn't work with generics
You can let the subclasses decide the return type of SomeMethod
.
abstract class Parent<TReturn> where TReturn : ReturnParent
{
public abstract TReturn SomeMethod();
}
class Child : Parent<ReturnChild>
{
public override ReturnChild SomeMethod(){}
}
If you make Parent<T>
implement the following covariant interface, then you could cast Child
to IParent<ReturnParent>
.
interface IParent<out T>
{
T SomeMethod();
}
If you want to make it castable specifically to Parent<ReturnParent>
, then no, that can't be done, and you may need a redesign.
This works with Linqpad
abstract class Parent<T>
{
public abstract T SomeMethod();
}
class Child : Parent<ReturnChild>
{
// Note the return type
public override ReturnChild SomeMethod()
{
return new ReturnChild();
}
}
void Main()
{
var p = new Child(); // This works
Child c = p as Child; // This doesn't work with generics
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.