2010-01-22 40 views
5

我能有這樣的事情:使用泛型方法,是否有可能從相同的方法獲取不同的類型?

int x = MyMethod<int>(); 
string y = MyMethod<string>(); 

所以,一個方法返回基於T.當然,不同類型,會有裏面的方法邏輯,以確保它返回正確的事情。

我永遠無法得到像這樣的東西來運行。它抱怨說,它不能返回值轉換爲T:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return 0; 
    } 
    else 
    { 
    return "nothing"; 
    } 
} 
+4

˚F首先,這段代碼不會編譯,因爲沒有指定返回類型。我假設你想要它讀取'公共靜態T MyMethod ()' – Nick 2010-01-22 21:51:44

+0

作爲你的答案,尼克。我認爲這是他需要的解決方案。 – JMD 2010-01-22 21:53:21

+0

...雖然上面編寫的代碼仍然不會編譯,因爲「Nothing」不是T,除非T是字符串,並且0不是T,除非T是數字類型。 – JMD 2010-01-22 21:54:53

回答

10

請嘗試以下

public static T MyMethod<T>() { 
    if (typeof(T) == typeof(Int32)) { 
    return (T)(object)0; 
    } else { 
    return (T)(object)"nothing"; 
    } 
} 

這裏的竅門是鑄造object。你試圖做的事情本質上是不安全的,因爲編譯器不能推斷0或「無」可轉換爲任何給定的T。畢竟它是無限的。所以,只需告訴編譯器將其轉換爲object並不安全。

+0

這個工程。所以,唯一覺得你做得不同的事情是先把它投射到一個物體上,然後再投射到T? – Deane 2010-01-22 22:03:34

+1

雖然這解決了編譯時錯誤,但它仍然沒有意義。如果T是一個頁面類型,那麼通過這個(對象)hack將一個字符串轉換爲T是沒有意義的。這個編譯的唯一原因是因爲字符串和整數都可以轉換爲對象,並且對象可以是它們的後代類型(即所有內容)的大小寫。 – 2010-01-22 22:17:08

0

如果你想要返回一個「null」類型的值,如果它不是int,你可以這樣做。但是如果你想在所有其他情況下使用字符串,請檢查其他答案。

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return (T)(object)0; 
    } 
    else 
    { 
    return default(T); // or null 
    } 
} 
+0

對於字符串示例,OP希望它返回特定的字符串值,而不是默認值(T)。您也缺少返回類型。 – JaredPar 2010-01-22 21:56:11

+0

真..我錯過了它,因爲我複製了代碼,並在編輯之前錯過了那部分。 – 2010-01-22 21:59:57

+0

這將不起作用 - int和T之間沒有轉換 – Lee 2010-01-22 22:00:34

0

@Nick在他的評論中是正確的,你的代碼不會編譯。但是,假設你的意思:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return 0; 
    } 
    else 
    { 
    return "nothing"; 
    } 
} 

它可能會非常棘手,使仿製藥非一般像你正試圖(和真正違反整點),但這應該工作:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return (T)(object)0; 
    } 
    else if(typeof(T) == typeof(string)) 
    { 
    return (T)(object)"nothing"; 
    } 

    return default(T); 
} 
+0

是的,這是與上述相同的解決方案。我假設我不得不首先投射到一個對象,因爲沒有從int到T的直接投射。但是有一個從int到object的對象,並且對象是T.是否正確? – Deane 2010-01-22 22:08:52

+0

因爲您檢查typeof(T)是。真的else子句應該檢查typeof(字符串),否則像MyMethod 會失敗。我將編輯示例。 – dkackman 2010-01-22 23:12:10

0

這ISN」 t有效,因爲不能保證T可以被轉換/可轉換爲字符串或int。泛型不是變體 - 即可以容納任何東西的類型 - 它們被編譯時解析爲真實類型。你的代碼不會編譯,因爲它不應該。您可以使用這裏發佈的一些黑客來解決編譯時問題,但這確實是一個邏輯問題。退後一步,重新思考你想要做什麼,而不是試圖繞過編譯器。

+0

我可以以某種方式約束T只能是字符串或整型? – Deane 2010-01-22 23:06:57

+0

@Deane - 你不能 – dkackman 2010-01-22 23:15:24

+0

@Deane - 在VB或類似的腳本語言中,你可以從函數返回你想要的任何東西 - int,string,float,page,webservice reference,你有什麼。在強類型語言中,情況並非如此 - 因爲編譯器希望你控制統治,而不是讓它爲你做你的工作。 CALLING CODE看起來像你需要這種結果?! – 2010-01-23 05:44:08

1

稍微偏離主題,但如果你試圖做這件事情那麼它可能是你的設計是錯誤的...

爲什麼不超載的方法和結果設置爲出放慢參數:

void MyMethod(out int result) 
{ 
    result=0; 
} 

void MyMethod(out string result) 
{ 
    result="my value"; 
} 

然後你就可以說:

int value; 
MyMethod(out value); 

,編譯器將選擇合適的版本

+0

對於不同類型使用相同的邏輯,它不是正確使用泛型嗎?我只是有一個方法,有一堆邏輯,但在不同的情況下,我需要不同的類型。這不是使用泛型的正確方法嗎? – Deane 2010-01-22 22:46:07

+0

但是你正在切換類型,這會導致問題...我會發佈一個替代 – Sean 2010-01-22 22:47:45

+0

是的,這將工作。看起來不那麼優雅,因爲我現在有三種方法 - 每種類型一種,核心邏輯一種。爲什麼打開鍵入問題? – Deane 2010-01-22 22:57:48

相關問題