2009-12-03 18 views
9

這裏是一些C#代碼無法編譯,給下面的消息:無法從「出T」轉換成「輸出分量」

不能從轉換「出來T」爲「輸出分量」

public void Get<T>(out T c) where T : Component 
    { 
     m_components.TryGetValue(typeof(T), out c); 
    } 

這裏是代碼,不會編譯:

public void Get<T>(out T c) where T : Component 
    { 
     Component temp; 
     m_components.TryGetValue(typeof(T), out temp); 
     c = (T)temp; 
    } 

我不知道爲什麼第一個代碼無效因爲「其中T:組件」明確指出T是類型組件。

感謝

+0

如果將T定義爲Component類型,爲什麼需要將「Get 」作爲泛型方法? 可能是你沒有提到這裏的確切場景。 – 2009-12-03 06:43:37

+3

* twiddles拇指等待Skeet先生在這個有趣的問題上啓發我們* – tster 2009-12-03 06:44:04

+0

這是一個重複。 http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302 – 2009-12-03 15:52:02

回答

4

我打算在@ Rex的答案的更精細的版本和稍微更正的@ Courtney的簽名版本中進行拍攝,因爲類型是Component,而不是對象。考特尼的回答基本上是正確的,只是類型有點偏離。

bool TryGetValue(Type key, out Component result) 
{ 
     if (this.Contains(key)) 
     { 
      result = this[key]; // the type of result is Component! 
      return true; 
     } 

     return false; 
} 

通過將T作爲對象類型,您試圖隱含投基類型組件的子類型T.這就是爲什麼你的第二個例子工程。 TryGetValue不知道你的泛型類型T,它認爲m_Components中的所有內容都是一個Component對象。

這是一個相當普遍的事情,被卡住的思想倒退。因爲它是一個參數,而不是返回類型,所以你會認爲它應該像任何其他參數一樣工作。但是,因爲這是而不是,實際上它更適合作爲此目的的返回類型......它將嘗試將其內部工作的值分配給您提供的參數。

3

我認爲這個問題是在,並沒有涉及到泛型

我們可以按照如下

class A 
{ 
} 

void fn(out object x) 
{ 
x= new object(); 
} 
void main() 
{ 
A x; 
fn(out x); //error 
} 
-2

這是有趣的產生同樣的錯誤。

我沒有答案,但值得注意的(對我來說,反正),即以下工作:

public void M<T> (out T c) where T : Test 
    { 
     // Test m; 
     // A(out m); 
     // c = (T) m; 

     A(out c); 
    } 

    public void A<T> (out T t) where T : Test 
    { 
     t = null; 
    } 

- 編輯:

(這很有趣,因爲即使是out object t它仍然是不可兌換的out T之間out object

12

這是因爲out參數類型不能covariant/contravariant變量的類型必須與參數類型完全匹配。

參見:

class Super { } 
class Sub : Super { } 

void Test(out Super s) 
{ 
    s = new Super(); 
} 

void Main() 
{ 
    Sub mySub = new Sub(); 
    Test(out mySub); //doesn't work 
} 
+0

你打我吧:( – FlySwat 2009-12-03 06:58:49

+0

很好的解釋和例子 – 2010-01-19 02:40:05

0

好了,我想通了:

如果你具備以下條件:

public class BaseClass { ... } 
public class SubClass : BaseClass { ... } 

然後我的代碼:

Dictionary<int, BaseClass> comps; 

public void Get<T>(int num, out T c) where T : BaseClass 
{ 
    comps.TryGetValue(num, out c); 
} 

An d我試圖爲這樣稱呼它:

SubClass sub; 
Get<SubClass>(1, out sub); 

子假設BaseClass爲1的關鍵竟是BaseClass而不是​​。也許這是OtherSubClass其中OtherSubClass : BaseClass

-2

我猜想,TryGetValue樣子:

bool TryGetValue (Type someType, out Object result){ 
    // do stuff// 
} 

從而resultobject而非component,不能隱式轉換,這正是你正在嘗試做的。