2015-04-03 42 views
1

我試圖做一些工作在C++中,但C#對我來說是一個挑戰。C#模板選項

我有一個解析,數據庫訪問,Web訪問/等等,並最終結束了一系列的字符串添加到容器的方法。有時候,我需要將其添加到HashSet或列表或等

因此,在C++中,這應該是這樣的:

<template T> 
bool GetStrings(T& container) 
{ 
    ... 
    std::string foo = "bar"; 
    ... 
    container.add(foo); // This statement is within a loop and if checks 
    ... 
    return true; 
} 

我想,在C#:

private bool GetStrings<T>(ref T cont) 
{ 
    string foo = "BAR"; 
    cont.Add(foo); // T does not contain a definition for Add ... 
    return true; 
} 

一同事建議使用容器的基類/接口。所以,我想這一點(看錶,的Hashset等都有一個共同的接口定義後):

private bool GetStrings(ref ICollection<string> cont) 
{ 
    string foo = "BAR"; 
    cont.Add(foo); 
    return true; 
} 

我希望能夠調用此方法是這樣的:

HashSet<string> a = new HashSet<string>(); 
List<string> b = new List<string>(); 
// etc other classes containing "Add" method 
if (GetString(ref a)) ... // These aren't all in one place, but spread out 
if (GetString(ref b)) ... // and the types are based on what is useful in 
if (GetString(ref c)) ... // each particular context. 
if (GetString(ref d)) ... 

現在的方法本身編譯,但我不能調用它。我得到最好的超載有無效的參數,「參數1:無法從‘參考System.Collections.Generic.List’轉換爲‘參考了System.Collections.Generic.ICollection’」

我想它只是一個類型轉換需要的東西。所以,我嘗試:

if (GetString(ref (ICollection<string>)a)) ... 

然後我得到「ref或out參數必須是可分配的變量」。所以,問題是......這可以在C#中完成,我完全是在錯誤的軌道上嗎?我也考慮傳遞一個Object ref並嘗試調用'GetType'和'GetMethod'等來確定Add是否可用,但是不知道如何調用Add方法。

回答

1

使用generic type constraints。 你可以做,編譯和運行如下:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Test t = new Test(); 

     HashSet<string> a = new HashSet<string>(); 
     List<string> b = new List<string>(); 

     if (t.GetString(ref a)) 
     { 

     } 
     if (t.GetString(ref b)) 
     { 

     } 
    } 

    public class Test 
    { 
     public bool GetString<T>(ref T cont) where T : ICollection<string> 
     { 
      string foo = "BAR"; 
      cont.Add(foo); 
      return true; 
     } 
    } 
} 

順便說所有集合都已經引用類型,除非你想改變原來的變量,裁判是沒有必要的。見here for an explanation

0

您需要使用通用約束你的方法:

private bool GetStrings<T>(T cont) where T : ICollection<string> 
{ 
    string foo = "BAR"; 
    // The compiler knows that T is always ICollection<string>, and can infer that Add 
    // is a valid method call 
    cont.Add(foo); 
    return true; 
} 

此外,你並不需要按引用傳遞你的清單 - 這已經是一個參考。用C++的說法,就像你在那裏傳遞一個指向指針的指針。