2012-12-27 23 views
1

我想用泛型編寫簡單的C#函數。例如數組解析器。通用函數錯誤

public static int parse_array <T> (string str, ref T[] array) 
    where T : IConvertible<T> 
{ 
    string[] vals=str.Split(new char[]{'','\t',',',';'}, StringSplitOptions.RemoveEmptyEntries); 

    if(vals==null || vals.Length==0) 
     return 0; 

    array = new T[vals.Length]; 

    for(int i=0; i<vals.Length; i++) 
    { 
     array[i] = Convert.ChangeType (vals[i], T); 
    } 

    return vals.Length; 
} 

但我得到錯誤:非泛型類型'System.IConvertable'不能與類型參數一起使用。 有什麼問題?

+2

僅供參考,C#沒有模板。它有「泛型」。它們與C++模板不一樣。 –

+0

一定要修正你的'Convert.ChangeType'行,它應該讀取'array [i] = Convert.ChangeType(vals [i],typeof(T));'(注意'typeof') –

+0

另一個錯誤:另一個錯誤:不能將類型'object'隱式轉換爲'T'。顯式轉換存在(是否缺少轉換?) – Newbee

回答

5

與您的特定編譯器錯誤的問題是,IConvertible不是通用接口,您的從句應該是:

where T : IConvertible 

where T : IConvertible<T> 

事實上,編譯器錯誤是告訴你,你是試圖將類型參數(即<T>)放在非泛型類型上(即接口IConvertible)。儘管一些接口是通用的或者具有通用並行接口,但IConvertible不是其中之一。

然後,另外,你要使用typeof(T)而不是T在您的來電ChangeType,因爲T是一個類型的名稱,而不是Type克里斯提到一個實例...

+0

「然後,另外,在調用ChangeType時,您需要使用typeof(T)而不是T,因爲T是類型名稱而不是Type的實例正如Chris提到的那樣...「 我將代碼更改爲: array [i] = Convert.ChangeType(vals [i],typeof(T)); 另一個錯誤:不能將類型'object'隱式轉換爲'T'。存在明確的轉換(是否丟失了cast?) – Newbee

+0

是的,'ChangeType()'返回'object',而不是'T'的實例,所以你需要強制轉換:'array [i] =(T)Convert '.ChangeType(vals [i],typeof(T));' –

+0

也就是說,它返回'vals [i]'轉換爲'T'類型,但返回爲'object',然後您必須轉換爲'T'類型。 (只是一個類型轉換,此時不是轉換)。 –

2

我見這已經得到了回答,猜測我有點慢。但我添加了一個更簡單的數組轉換實現。

public static int parse_array<T>(string str, ref T[] array) where T : IConvertible 
{ 
    string[] vals = str.Split(new char[] { '\t', ',', ';' }, StringSplitOptions.RemoveEmptyEntries); 

    if (vals == null || vals.Length == 0) 
     return 0; 

    array = Array.ConvertAll<string, T>(vals, (o) => (T)Convert.ChangeType(o, typeof(T))); 

    return vals.Length; 
} 
+0

非常感謝! – Newbee