2017-01-05 100 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