2017-01-05 70 views
2

随着抽象下面的类:C#泛型抽象方法调用

public abstract class A 
{ 
    public static string MyMethod() 
    { 
     return "a"; 
    } 
} 

我为什么不能建这个派生抽象类:

public class B<T> where T : A 
{ 
    public void AnotherMethod() 
    { 
     var S1 = base.MyMethod(); // not allowed 
     var S2 = T.MyMethod();  // not allowed 
    } 
} 

我不明白为什么,因为的MyMethod会可用于类型T

+0

在C#中,静态方法调用总是在编译时静态解析。静态方法不参与继承。 – recursive

+2

为什么'var S2 = A.MyMethod();',因为你知道上面的'A'? –

+1

'基地。MyMethod()'不会工作,因为B不会继承A,它的类型参数仅限于A的实现,这是递归注释的来源。 – Phaeze

回答

3

在你的问题中有两个误解,它们共同阻止你的工作尝试。

首先你的B类不是从A类派生的,你只是说它需要一个通用参数,它必须从A继承。

其次为用户@recursive指出,静态方法不参与继承,以便MyMethod将永远只能是可作为A.MyMethod()

可以使至少你的第一次尝试工作,如果你删除static修饰符,使B从A继承而不是使用泛型。

// Removed the static modifier 
public abstract class A 
{ 
    public string MyMethod() 
    { 
     return "a"; 
    } 
} 

// Made B inherit directly from A 
public class B : A 
{ 
    public void AnotherMethod() 
    { 
     var S1 = base.MyMethod(); //base technically isn't required 
    } 
} 
+0

我现在明白了;我的印象是,B:某种程度上产生了与B 相同的属性,其中T:A – Thomas

+0

@Thomas,真棒,很高兴我能够帮助 – Phaeze

3

除了一个事实,即A.MyMethod是静态的,这显然不会因为任何静态不参与继承工作,即使你做它不是静态的它仍然是行不通的。例如,这也不起作用:

public abstract class A { 
    public string MyMethod() { 
     return "a"; 
    } 
} 

public class B<T> where T : A { 
    public void AnotherMethod() { 
     var S1 = base.MyMethod(); // Line 1 
     var S2 = T.MyMethod();  // Line 2 
    } 
} 

为什么?

您的意思是where T : A这意味着类型T必须是来自A的派生类型。您的课程B<T不是派生类型A,因此第1行将不起作用。

但为什么2号线不工作?

T是一种类型,如果T是继承A,然后T类型的对象就可以做到这一点。如果你改变了它这个样子,那么它会工作:

public abstract class A { 
    public string MyMethod() { 
     return "a"; 
    } 
} 

public class B<T> where T : A { 
    public void AnotherMethod(T t) { 
     t.MyMethod(); 
    } 
} 

public class C : A { 

} 

public class BClosed : B<C> { 
    public void Foo(C c) { 
     c.MyMethod(); 
     this.AnotherMethod(c); 
    } 
} 

在上面的代码,C派生A这是你的限制。然后BClosed关闭通用类型说TC所以现在你可以拨打电话MyMethodAAnotherMethod你的通用。

此外,当你有一个泛型类,你应该使用泛型类型,否则我没有看到使用。所以这是没用的,因为它没有通用的代码:

public class B<T> where T : A { 
    public void AnotherMethod() { 

    } 
} 
+0

这非常明显!谢谢! – Thomas

+0

非常好的细节来涵盖问题的通用方面。 – Phaeze