I have a Function in C# and it have to return the type of the Class. Also in subclasses which extends the class.
Like:
public class A
{
public typeof(this) Method()
{
//Code
}
}
public class B : A {
public override typeof(this) Method() {
//Code
}
}
So the Method in class A should have the return type A. And the Method in class B should have the return tpye B.
Is there a way to do it?
No, this isn't possible. What you're asking for is called a covariant return type, but C# doesn't support this. The closest you can get is either this:
public class A
{
public virtual A Method()
{
//Code returning an A
}
}
public class B : A
{
public override A Method()
{
//Code returning a B
}
}
Which is legal because every B
is also an A
, or you can use generics instead of inheritance:
public class Foo<T>
{
public virtual T Method()
{
//Code
}
}
And then you can have Foo<A>
and Foo<B>
-- however, Foo
cannot depend on any specifics of T
. You can combine this with inheritance, which will sort of achieve what you want:
public class A : Foo<A>
{
// And now A has a Method that returns A
}
public class B : Foo<B>
{
// And now B has a Method that returns B
}
But the problem with this approach is that you will have a hard time actually implementing Method
in a meaningful way, because in Foo
you cannot use anything specific to the type. To make this explicit, you could make Method
abstract:
public abstract class Foo<T>
{
public abstract T Method();
}
public class A : Foo<A>
{
public override A Method()
{
// Code
}
}
public class B : Foo<B>
{
public override B Method()
{
// Code
}
}
I'm having a hard time imagining a scenario where you can actually make use of this, but at least it meets the requirements.
Last but not least, you are not required to use inheritance -- does B
really need to derive from A
or could you inherit from some common base that does not use Method
?
Depending on what your method is trying to do, it might be possible to achieve what you want by using extension methods.
public class A { }
public class B : A { }
public static class AExtension {
public static T Method<T>(this T target) where T: A {
// do your thing here.
return target; // or, return a new instance of type T.
}
}
You can then call Method()
and let C# infer the generic argument:
var a = new A();
a = a.Method(); // C# will infer T as A.
var b = new B();
b = b.Method(); // C# will infer T as B.
The downside to this approach is, of course, that you cannot access non-public members of your classes in Method()
, unless you use reflection.
There is a way to do this, actually.
class A {
public A Method () { ... return this; }
}
class B : A {
new public B Method () => (B)base.Method();
// or { base.Method(); return this; }
}
Make sure you only use this if you know that the base returns this
.
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.