C# 返回类型应该是 this.getType()

本文关键字:getType this 返回类型 | 更新日期: 2023-09-27 18:33:18

我在C#中有一个函数,它必须返回类的类型。也在扩展类的子类中。

喜欢:

public class A
{
    public typeof(this) Method()
    {
        //Code
    }
}
public class B : A {
    public override typeof(this) Method() {
        //Code
    }
}

因此,类 A 中的方法应具有返回类型 A。并且 B 类中的方法应该有返回 tpye B。

有没有办法做到这一点?

C# 返回类型应该是 this.getType()

不,这是不可能的。你所要求的称为协变返回类型,但 C# 不支持此类型。您可以获得的最接近的是:

public class A
{
    public virtual A Method()
    {
        //Code returning an A
    }
}
public class B : A 
{
    public override A Method() 
    {
        //Code returning a B
    }
}

这是合法的,因为每个B也是一个A,或者您可以使用泛型而不是继承:

public class Foo<T>
{
    public virtual T Method()
    {
        //Code
    }
}

然后你可以有Foo<A>Foo<B> - 但是,Foo不能依赖于T的任何细节。您可以将其与继承相结合,这将实现您想要的:

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
}

但是这种方法的问题在于,您将很难以有意义的方式实际实现Method,因为Foo您不能使用特定于该类型的任何内容。为了明确这一点,你可以做Method抽象:

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
    }
}

我很难想象一个场景,你可以实际使用它,但至少它符合要求。

最后但并非最不重要的一点是,您不需要使用继承 - B真的需要从A派生,还是您可以从不使用Method的某个公共基础继承?

根据您的方法尝试执行的操作,可以使用扩展方法实现所需的内容。

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.
    }
}

然后,可以调用 Method() 并让 C# 推断泛型参数:

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.

当然,这种方法的缺点是,除非你使用反射,否则你不能在Method()中访问类的非公共成员。

实际上,有一种方法可以做到这一点。

class A {
    public A Method () { ... return this; }
}
class B : A {
    new public B Method () => (B)base.Method();
    // or { base.Method(); return this; }
}

确保仅在知道基本返回 this 时才使用它。