2010-11-24 46 views
10

通常你想發送多個值,但由於使用率低(即它只用在一兩個地方),很難證明創建一個新類型是合理的。在C#中使用元組更容易的任何提示?

Tuple<...>KeyValuePair<,>類型非常有用,但它們沒有真正的語言支持。

好吧,用於元組列表的一個很好的技巧是創建一個擴展列表並添加自定義添加方法的類型:

public class TupleList<T1,T2> : List<Tuple<T1,T2>>{ 
    public void Add(T1 key, T2 value){ 
     base.Add(Tuple.Create(key, value)); 
    } 
} 

這意味着,如果我有需要的IEnumerable<Tuple<int,string>>的方法,我可以使用下面的代碼來快速建立名單,像這樣::

Foo(new TupleList<int,string>{{1,"one"},{2,"two"},{3,"three"}}); 

這使得纏繞值到一個元組列表更容易,因爲我們不必一直說Tuple.Create,並且讓我們幾乎可以看到一個很好的函數式語言語法。

但是,使用元組時,將其展開到不同的組件中很有用。這種擴展方法可能在這方面很有用::

public static void Unwind<T1,T2>(this Tuple<T1,T2> tuple,out T1 var1,out T2 var2) 
    { 
     var1 = tuple.Item1; 
     var2 = tuple.Item2; 
    } 

但即使這樣很煩人,因爲out參數根本不是變體。這就是說,如果T1是一個字符串,即使它們是可賦值的,我也不能發送一個對象變量,但是如果我可以用手來展開的話。我無法真正地提出你爲什麼會想要這種變化的原因,但如果它在那裏,我不明白爲什麼你會想要失去它。

任何人都有其他技巧,使工作元組,或元組對象更容易在C#中的對象?

元組的重要潛在用途可能是通用記憶。在F#等語言中這很容易,但在C#中很難。

我目前正在使用元組提供一個MethodBase和一個標記數組(常量,對象或自變量標記),提供給動態構建的對象來構造某些成員字段。

由於我想讓API使用者的語法更加簡單,我創建了Add方法,可以使用ConstructorInfoMethodInfo和params對象數組。

編輯: 埃裏克利珀像往常一樣具有優良的動機在這裏使用元組,他甚至說,我懷疑真的是沒有支持: What requirement was the tuple designed to solve?

+0

你能告訴我們你的用例嗎?在這種用例中,你最好傳入`object`類型的參數,而不是鍵入它們實際應用的變量?即向我們展示您希望如何使用一點上下文來調用「放鬆」。 – 2010-11-24 17:37:17

+1

輸出參數是嚴格的,這就是爲什麼他們不建議作爲選擇。我會殺死像F#這樣的API支持,將參數變成元組。 – 2010-11-24 18:49:27

回答

5

在C#中,你可以別名封閉泛型類型,哪一個數組就像使用代碼

Tuple<string, string, string, int, string> ParseUri (string url); 

的方法,這使您能夠提供一些更好的洞察什麼是打算。不會更改代碼,但如果您查看下面的示例,GetTemp返回的意圖會更好。

沒有別名:

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var result = GetTemp(10, 10); 
      Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1); 
     } 

     // You give a lat & a long and you get the closest city & temp for it 
     static Tuple<double, string> GetTemp(double lat, double @long) 
     { 
      // just for example 
      return Tuple.Create(10d, "Mordor"); 
     }   
    } 
} 

有了別名:

namespace ConsoleApplication1 
{ 
    using CityTemp = Tuple<double, string>; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var result = GetTemp(10, 10); 
      Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1); 
     } 

     // You give a lat & a long and you get the closest city & temp for it 
     static CityTemp GetTemp(double lat, double @long) 
     { 
      // just for example    
      return new CityTemp(10, "Mordor"); 
     } 
    } 
} 
2

會有用C#來了一個真棒元組功能7 /視覺工作室15

基本上你可以做soething like that

static (int x, int y) DoSomething() 
{ 
    return (1, 2); 
} 

static void Test() 
{ 
    var cool = DoSomething(); 
    var value = cool.x; 
} 

根據post閱讀