[英]What's the best way of using a pair (triple, etc) of values as one value in C#?
也就是說,我想要一個價值元組。
我心中的用例:
Dictionary<Pair<string, int>, object>
要么
Dictionary<Triple<string, int, int>, object>
是否有內置類型,如Pair或Triple? 或者實施它的最佳方式是什么?
更新答案中描述了一些通用元組實現,但對於在字典中用作鍵的元組,您應該另外驗證哈希碼的正確計算。 在另一個問題中有關於此的更多信息。
更新2我想還值得提醒的是,當你在字典中使用某個值作為鍵時,它應該是不可變的。
在某些特定情況下,.net框架已經提供了類似元組的類,您可以利用它們。
對和三人組
通用的System.Collections.Generic.KeyValuePair類可以用作adhoc對實現。 這是泛型Dictionary在內部使用的類。
或者,您可以使用System.Collections.DictionaryEntry結構,該結構充當基本對,並具有在mscorlib中可用的優勢。 然而,不利的是,這種結構不是強類型的。
還可以以System.Web.UI.Pair和System.Web.UI.Triplet類的形式提供Pairs和Triple。 盡管這些類存在於System.Web程序集中,但它們可能非常適合winforms開發。 但是,這些類也不是強類型的,也可能不適用於某些場景,例如通用框架或庫。
更高階的元組
對於更高階的元組,如果沒有滾動自己的類,可能沒有一個簡單的解決方案。
如果已安裝F#語言 ,則可以引用包含一組通用不可變Microsoft.Fsharp.Core.Tuple類的FSharp.Core.dll ,直到通用的六進制文件。 但是,即使可以重新分發未修改的FSharp.Code.dll ,F#也是一種研究語言並且正在進行中,因此這種解決方案可能只對學術界有興趣。
如果您不想創建自己的類並且引用F#庫感到不舒服,那么一個很好的技巧可能在於擴展通用KeyValuePair類,以便Value成員本身就是嵌套的KeyValuePair。
例如,以下代碼說明了如何利用KeyValuePair創建Triples:
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
這允許根據需要將類擴展到任意級別。
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>();
KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string> quintuple =
new KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string>();
在其他情況下,您可能需要求助於滾動自己的元組類,這並不難。
您可以創建簡單的結構,如下所示:
struct Pair<T, R>
{
private T first_;
private R second_;
public T First
{
get { return first_; }
set { first_ = value; }
}
public R Second
{
get { return second_; }
set { second_ = value; }
}
}
之前已經解決了這個問題,並且確實存在通用框架。 以下是一個這樣的框架的鏈接:
public struct Pair<T1, T2>
{
public T1 First;
public T2 Second;
}
public struct Triple<T1, T2, T3>
{
public T1 First;
public T2 Second;
public T3 Third;
}
快進到2010年,.NET 4.0現在支持任意n的n元組 。 這些元組按預期實現結構上的平等和比較。
我在C#中實現了一個元組庫。 訪問http://www.adventuresinsoftware.com/generics/並單擊“元組”鏈接。
我通常只創建自己的結構,包含值。 它通常更具可讀性;)
如果您不想創建自己的類, KeyValuePair是最好的擴展類。
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
您可以將其擴展到任意數量的級別。
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string>();
注 : 三聯和對存在的System.Web -dll中的類,所以它不是很適合ASP.NET比其他解決方案。
您可以相對輕松地創建自己的元組類,唯一可能變得混亂的是您的相等和哈希碼覆蓋(如果您要在字典中使用它們,則必不可少)。
應該注意的是.Net自己的KeyValuePair<TKey,TValue>
struct具有相對較慢的相等和哈希碼方法 。
假設這不是你的問題,那么仍然存在代碼最終難以弄清楚的問題:
public Tuple<int, string, int> GetSomething()
{
//do stuff to get your multi-value return
}
//then call it:
var retVal = GetSomething();
//problem is what does this mean?
retVal.Item1 / retVal.Item3;
//what are item 1 and 3?
在大多數情況下,我發現創建一個特定的記錄類更容易(至少在C#4使這個編譯器變得神奇之前)
class CustomRetVal {
int CurrentIndex { get; set; }
string Message { get; set; }
int CurrentTotal { get; set; }
}
var retVal = GetSomething();
//get % progress
retVal.CurrentIndex / retVal.CurrentTotal;
尚未提及一個簡單的解決方案。 您也可以使用List<T>
。 它內置,高效且易於使用。 當然,它起初看起來有點奇怪,但它完美地完成了它的工作,特別是對於更多的元素數量。
NGenerics--流行的.Net算法和數據結構庫,最近向該集合引入了不可變數據結構。
實現的第一個不可變的是pair和tuple類。 代碼完全覆蓋了測試,非常優雅。 你可以在這里查看 。 他們目前正在研究其他不可改變的替代方案,他們應該很快做好准備。
沒有內置的ins,但是Pair <T,R>類很容易創建。
是的,有System.Web.UI.Pair和System.Web.UI.Triplet(它有一個重載的對象類型行為的創建者!)
對於第一種情況,我通常使用
Dictionary<KeyValuePair<string, int>, object>
沒有內置的類。 您可以使用KeyValuePair或推出自己的實現。
您可以使用System.Collections.Generic.KeyValuePair作為您的Pair實現。
或者你可以實現自己的,他們並不難:
public class Triple<T, U, V>
{
public T First {get;set;}
public U Second {get;set;}
public V Third {get;set;}
}
當然,有一天你可能會遇到Triple(string,int,int)與Triple(int,int,string)不兼容的問題。 也許改為使用System.Xml.Linq.XElement。
F#中還有Tuple <>類型; 你只需要參考FSharp.Core.dll。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.