2013-01-11 174 views
3

爲什麼這是不可能的?C#:使用類泛型參數覆蓋泛型方法

abstract class A 
{ 
    public abstract T f<T>(); 
} 

class B<T> : A 
{ 
    public override T f() 
    { 
     return default (T); 
    } 
} 

錯誤:

does not implement inherited abstract member 'A.f<T>()' 
no suitable method found to override 

我知道,簽名必須是相同的,但是從我的角度我認爲沒有理由怎麼可能是錯的,這是被禁止的。 另外我知道另一個解決方案是使A泛型,而不是它的方法,但它由於某種原因不適合我。

回答

4

B未履行合同A

A允許用任何類型參數調用f來返回該類型。 B不允許使用類型參數調用f,並且只返回B類型參數的類型。

例如,假設你有一個B<int>並將其轉換爲A(這應該是可能的,因爲它是從它繼承的)。然後你打電話給f<bool>()(這應該是可能的,因爲它是A)。然後怎樣呢?底層的B<int>沒有可調用的方法。

B b = new B<int>(); 
// This is legal as B inherits from A 
A a = b; 
// This is a legal call, but how does b handle it? 
bool result = a.f<bool>(); 
+0

> B只允許f用B的類型參數調用 B根本沒有通用方法'f'所以B甚至不允許f用B的類型參數調用 –

+0

@RuneFS我不是那個意思從字面上;我會更清楚。 – Rawling

+0

很好的答案...我認爲這是以最好的方式解釋原因。 – Zoka

5

這是不可能的,因爲這些方法有不同的簽名。 A.f是通用方法,B.f不是(它僅使用類泛型參數)。

你可以看到這種形式的調用者的角度:

A variableA = new A(); 
variableA.f<int>(); 

B<int> variableB = new B<int>(); 
variableB.f(); 
+0

我知道簽名是不同的。但是,如果我在創建時指定泛型參數,而不是在調用該方法時不一樣嗎? 我這樣看:T A.f()== T B.f() - 兩種方法都採用相同的參數,並返回相同的類型,所以我錯過了什麼問題? – Zoka

+0

不,它不是。您可以輕鬆聲明包含泛型方法的泛型類。您在爭論C#如何設計,您有兩個選擇接受它或更改語言。 – Rafal

0

也許這是你打算做什麼:

abstract class A 
{ 
    public abstract T f<T>(); 
} 

class B<U> : A 
{ 
    public override T f<T>() //also needs to have a generic type parameter 
    { 
     throw new NotImplementedException(); 
    } 

    public U f() 
    { 
     return f<U>(); 
    } 
} 

用的一般方法類型參數和泛型類的類型參數(這裏TU)沒有直接的連接,即T在基類中不限於U(或其他),並且不能在派生類中更改此限制。

1

在你的代碼的情況下

abstract class A 
{ 
    public abstract T f<T>(); 
} 

class B<T> : A 
{ 
    public override T f() 
    { 
     return default (T); 
    } 
} 

你有什麼期望在下面的代碼

public void Foo(A myObj) { 
    myObj.f<DateTime>(); 
} 
Foo(new B<int>()); 

被稱爲有因爲雖然類型合同該方法沒有實現(抽象類A)明確指出你需要一個實現。所以,你可以實現或變更合同使用類型參數在類級別

abstract class A<T> 
{ 
    public abstract T f(); 
} 

class B<T> : A<T> 
{ 
    public override T f() 
    { 
     return default (T); 
    } 
} 

並編譯但同時也限制了˚F當然

+0

我的想法是 A myObj = new B (); myObj.f(); 注意缺少調用'f'的'DateTime'。我想在創建過程中說,這個類使用T作爲所有函數的通用參數。 – Zoka

+1

@Zoka你說的對「所有功能_」。但'f '是基類的功能,而派生類的類型參數對它沒有影響力。它是基類方法的類型參數 - 方法級別,而不是類。 – horgh

+0

現在......符文FS的最後一個例子在這裏:我可以爲類和覆蓋命名泛型參數相同的名稱,它真的編譯,並警告 - 但它是做什麼的?我的猜測是它只是隱藏在overriden方法中使用的類參數,對吧? – Zoka

0
abstract class A 
{ 
    public abstract T f<T>(); 
} 

class B<T> : A 
{ 
    public override T f<T>() 
    { 
     return default (T); 
    } 
} 
+0

我知道解決方案,我想知道爲什麼? – Zoka

+0

這是一個正確的方法,它的quastion與「我不能覆蓋方法'公共抽象無效Func()'作爲'公衆覆蓋布爾Func(詮釋數字)爲什麼?簽名不符 –