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

时间:2014-12-06 20:01:49

标签: c# generics this

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

像:

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

    public override typeof(this) Method() {
        //Code
    }
}

所以A类中的Method应该有返回类型A.而B类中的Method应该返回tpye B.

有办法吗?

3 个答案:

答案 0 :(得分:2)

不,这是不可能的。你要求的是一个协变返回类型,但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
}

但这种方法的问题在于,您将很难以有意义的方式实现 {/ em> 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

答案 1 :(得分:0)

根据您的方法尝试执行的操作,可以通过使用扩展方法来实现所需的功能。

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()中类的非公共成员。

答案 2 :(得分:0)

实际上有一种方法。

class A {
    public A Method () { ... return this; }
}

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

请确保仅在知道基准返回this的情况下使用此功能。