C ++ std :: pair का C # एनालॉग क्या है?


284

मुझे दिलचस्पी है: std::pairC ++ में C # का एनालॉग क्या है ? मुझे System.Web.UI.Pairकक्षा मिली , लेकिन मैं कुछ टेम्पलेट-आधारित पसंद करूंगा।

धन्यवाद!


11
मेरे पास कुछ समय पहले ऐसा ही अनुरोध था, लेकिन जितना मैंने इसके बारे में सोचा था, आप सामान्य "प्रथम" और "दूसरा" के बजाय स्पष्ट वर्ग प्रकारों और क्षेत्रों के साथ अपनी खुद की जोड़ी वर्ग को रोल करना चाह सकते हैं। यह आपके कोड को अधिक पठनीय बनाता है। एक युग्मन वर्ग 4 पंक्तियों के रूप में छोटा हो सकता है, इसलिए आप एक सामान्य जोड़ी <T, U> वर्ग का पुन: उपयोग करके अधिक बचत नहीं कर रहे हैं और आपका कोड अधिक पठनीय होगा।
मार्क लकाटा

जवाबों:


325

Tuples .NET4.0 के बाद से उपलब्ध हैं और जेनरिक का समर्थन करते हैं:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

पिछले संस्करणों में आप System.Collections.Generic.KeyValuePair<K, V>निम्न की तरह उपयोग या एक समाधान कर सकते हैं :

public class Pair<T, U> {
    public Pair() {
    }

    public Pair(T first, U second) {
        this.First = first;
        this.Second = second;
    }

    public T First { get; set; }
    public U Second { get; set; }
};

और इसे इस तरह उपयोग करें:

Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);

यह आउटपुट:

test
2

या यहां तक ​​कि इस जंजीर जोड़े:

Pair<Pair<String, int>, bool> pair = new Pair<Pair<String, int>, bool>();
pair.First = new Pair<String, int>();
pair.First.First = "test";
pair.First.Second = 12;
pair.Second = true;

Console.WriteLine(pair.First.First);
Console.WriteLine(pair.First.Second);
Console.WriteLine(pair.Second);

यह आउटपुट:

test
12
true

एक समान विधि जोड़ने के बारे में मेरी पोस्ट देखें
एंड्रयू स्टीन

टपल <> अब एक बेहतर उपाय है।
dkantowitz 7

6
चूँकि जेनेरिक क्लास से संबंधित प्रकार के मापदंडों को ऑब्जेक्ट क्रिएशन एक्सप्रेशन (कंस्ट्रक्टर कॉल) में नहीं बांधा जा सकता है, BCL के लेखकों ने एक गैर-जेनेरिक हेल्पर क्लास बनाया है Tuple। इसलिए आप कह सकते हैं कि Tuple.Create("Hello", 4)जो थोड़ा आसान है new Tuple<string, int>("Hello", 4)। (वैसे, .NET4.0 2010 से पहले से ही यहां मौजूद है।)
जेपी स्टिग नीलसन

4
मन आप Tuple<>ठोस Equalsऔर GetHashCodeमूल्य शब्दार्थ के साथ लागू करते हैं जो महान है। अपने खुद के ट्यूपल्स को लागू करते समय ध्यान रखें।
नवाफाल

यह स्पष्ट रूप से
इक्वाल्स

90

System.Web.UIइसमें Pairवर्ग समाहित है क्योंकि इसे ASP.NET 1.1 में आंतरिक ViewState संरचना के रूप में उपयोग किया गया था।

अद्यतन अगस्त 2017: C # 7.0 / .NET फ्रेमवर्क 4.7 System.ValueTupleसंरचना का उपयोग करके नामित वस्तुओं के साथ एक टपल घोषित करने के लिए एक सिंटैक्स प्रदान करता है ।

//explicit Item typing
(string Message, int SomeNumber) t = ("Hello", 4);
//or using implicit typing 
var t = (Message:"Hello", SomeNumber:4);

Console.WriteLine("{0} {1}", t.Message, t.SomeNumber);

अधिक सिंटैक्स उदाहरणों के लिए MSDN देखें ।

अद्यतन जून 2012: Tuples संस्करण 4.0 के बाद से .NET का एक हिस्सा रहा है।

यहाँ है एक पहले लेख शामिल किए जाने in.NET4.0 का वर्णन और जेनरिक के लिए समर्थन:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

2
ध्यान दें कि ट्यूपल्स केवल-पढ़ने के लिए हैं। यही है, आप ऐसा नहीं कर सकते:tuple.Item1 = 4;
आकाश

2
टुपल्स बिल्कुल वही हैं जिसकी मुझे तलाश थी। धन्यवाद।
ग्लिगनैन

38

दुर्भाग्य से, कोई नहीं है। आप System.Collections.Generic.KeyValuePair<K, V>कई स्थितियों में उपयोग कर सकते हैं ।

वैकल्पिक रूप से, आप टुपल्स को संभालने के लिए अनाम प्रकारों का उपयोग कर सकते हैं, कम से कम स्थानीय रूप से:

var x = new { First = "x", Second = 42 };

अंतिम विकल्प खुद की क्लास बनाना है।


2
बस स्पष्ट होने के लिए, अनाम प्रकार भी केवल पढ़ने के लिए हैं - msdn
bsegraves


11

कुछ उत्तर गलत लगते हैं,

  1. आप शब्दकोश का उपयोग नहीं कर सकते हैं कि जोड़े (ए, बी) और (ए, सी) को कैसे स्टोर करेंगे। जोड़े की अवधारणा को कुंजी और मूल्यों के साहचर्य के साथ भ्रमित नहीं होना चाहिए
  2. उपरोक्त कोड का बहुत कुछ संदिग्ध लगता है

यहाँ मेरी जोड़ी क्लास है

public class Pair<X, Y>
{
    private X _x;
    private Y _y;

    public Pair(X first, Y second)
    {
        _x = first;
        _y = second;
    }

    public X first { get { return _x; } }

    public Y second { get { return _y; } }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        Pair<X, Y> other = obj as Pair<X, Y>;
        if (other == null)
            return false;

        return
            (((first == null) && (other.first == null))
                || ((first != null) && first.Equals(other.first)))
              &&
            (((second == null) && (other.second == null))
                || ((second != null) && second.Equals(other.second)));
    }

    public override int GetHashCode()
    {
        int hashcode = 0;
        if (first != null)
            hashcode += first.GetHashCode();
        if (second != null)
            hashcode += second.GetHashCode();

        return hashcode;
    }
}

यहाँ कुछ परीक्षण कोड है:

[TestClass]
public class PairTest
{
    [TestMethod]
    public void pairTest()
    {
        string s = "abc";
        Pair<int, string> foo = new Pair<int, string>(10, s);
        Pair<int, string> bar = new Pair<int, string>(10, s);
        Pair<int, string> qux = new Pair<int, string>(20, s);
        Pair<int, int> aaa = new Pair<int, int>(10, 20);

        Assert.IsTrue(10 == foo.first);
        Assert.AreEqual(s, foo.second);
        Assert.AreEqual(foo, bar);
        Assert.IsTrue(foo.GetHashCode() == bar.GetHashCode());
        Assert.IsFalse(foo.Equals(qux));
        Assert.IsFalse(foo.Equals(null));
        Assert.IsFalse(foo.Equals(aaa));

        Pair<string, string> s1 = new Pair<string, string>("a", "b");
        Pair<string, string> s2 = new Pair<string, string>(null, "b");
        Pair<string, string> s3 = new Pair<string, string>("a", null);
        Pair<string, string> s4 = new Pair<string, string>(null, null);
        Assert.IsFalse(s1.Equals(s2));
        Assert.IsFalse(s1.Equals(s3));
        Assert.IsFalse(s1.Equals(s4));
        Assert.IsFalse(s2.Equals(s1));
        Assert.IsFalse(s3.Equals(s1));
        Assert.IsFalse(s2.Equals(s3));
        Assert.IsFalse(s4.Equals(s1));
        Assert.IsFalse(s1.Equals(s4));
    }
}

3
यदि आप IEquatable को लागू नहीं करते हैं तो आपको मुक्केबाजी मिलेगी। अपनी कक्षा को सही ढंग से पूरा करने के लिए अधिक काम करना है।
जैक

8

यदि यह शब्दकोशों और पसंद के बारे में है, तो आप System.Collections.Generic.KeyValuePair <TKey, TValue> ढूंढ रहे हैं।


3

आप जो हासिल करना चाहते हैं, उसके आधार पर, आप KeyValuePair को आज़माना चाहते हैं ।

तथ्य यह है कि आप एक प्रविष्टि की कुंजी को बदल नहीं सकते बेशक KeyValuePair के एक नए उदाहरण द्वारा पूरी प्रविष्टि को प्रतिस्थापित करके ठीक किया जा सकता है।



2

मैं एक ही सवाल पूछ रहा था अभी एक त्वरित Google के बाद मैंने पाया कि .NET में एक जोड़ी वर्ग है। इसके सिवाय System.Web.UI ^ ~ ^ (http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) अच्छाई यह जानती है कि उन्होंने संग्रह रूपरेखाओं के बजाय इसे वहाँ क्यों रखा है


मैं System.Web.UI.Pair के बारे में जानता हूं। हालांकि सामान्य वर्ग चाहता था।
अलेक्जेंडर प्रोकोफयेव

System.Web.UI.air सील है। आप इसे प्राप्त नहीं कर सकते हैं (यदि आप सुरक्षित एक्सेसर्स जोड़ना चाहते हैं तो)।
मार्टिन वोब्र

2

.NET 4.0 के बाद से आपके पास System.Tuple<T1, T2>क्लास है:

// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);


नीचे वे कहते हैं: संस्करण सूचना नेट फ्रेमवर्क में समर्थित: 4
अलेक्जेंडर प्रोकोफ़ेव

2
@ अलेक्सेंडर: ठीक है, ठीक है। (हालांकि यह मुझे आश्चर्यचकित करता है कि उन्होंने यह पृष्ठ .NET 3.5-विशिष्ट क्यों बनाया है)
सर्ज मिखाइलोव

2

मैं आम तौर Tupleपर अपने स्वयं के सामान्य आवरण में कक्षा का विस्तार करता हूं :

public class Statistic<T> : Tuple<string, T>
{
    public Statistic(string name, T value) : base(name, value) { }
    public string Name { get { return this.Item1; } }
    public T Value { get { return this.Item2; } }
}

और इसे इस तरह उपयोग करें:

public class StatSummary{
      public Statistic<double> NetProfit { get; set; }
      public Statistic<int> NumberOfTrades { get; set; }

      public StatSummary(double totalNetProfit, int numberOfTrades)
      {
          this.TotalNetProfit = new Statistic<double>("Total Net Profit", totalNetProfit);
          this.NumberOfTrades = new Statistic<int>("Number of Trades", numberOfTrades);
      }
}

StatSummary summary = new StatSummary(750.50, 30);
Console.WriteLine("Name: " + summary.NetProfit.Name + "    Value: " + summary.NetProfit.Value);
Console.WriteLine("Name: " + summary.NumberOfTrades.Value + "    Value: " + summary.NumberOfTrades.Value);

1

काम करने के लिए उपरोक्त प्राप्त करने के लिए (मुझे एक शब्दकोश की कुंजी के रूप में एक जोड़ी की आवश्यकता थी)। मुझे जोड़ना था:

    public override Boolean Equals(Object o)
    {
        Pair<T, U> that = o as Pair<T, U>;
        if (that == null)
            return false;
        else
            return this.First.Equals(that.First) && this.Second.Equals(that.Second);
    }

और एक बार मैंने ऐसा किया कि मैंने भी जोड़ा

    public override Int32 GetHashCode()
    {
        return First.GetHashCode() ^ Second.GetHashCode();
    }

एक संकलक चेतावनी को दबाने के लिए।


1
आपको इससे बेहतर हैश-कोड एल्गोरिथ्म ढूंढना चाहिए, 37 + 23 * (h1 + 23 * (h2 + 23 * (h3 + ...)) का उपयोग करके देखें) यह (ए, बी) से अलग (बी, ए) बना देगा ), अर्थात। पुन: व्यवस्थित करने से कोड पर प्रभाव पड़ेगा।
लास वी। कार्लसन

टिप्पणी स्वीकार की जाती है .. मेरे मामले में मैं सिर्फ संकलक को दबाने की कोशिश कर रहा था, और वैसे भी टी एक स्ट्रिंग और यू एक इंट 32 है ...
एंड्रयू स्टीन


1

कस्टम क्लास या .Net 4.0 ट्यूपल्स के अलावा, C # 7.0 के बाद से एक नया फीचर है, जिसका नाम ValueTuple है, जो एक ऐसी संरचना है जिसे इस मामले में इस्तेमाल किया जा सकता है। लिखने के बजाय:

Tuple<string, int> t = new Tuple<string, int>("Hello", 4);

और के माध्यम से t.Item1और मूल्यों का उपयोग t.Item2, आप बस इसे इस तरह कर सकते हैं:

(string message, int count) = ("Hello", 4);

या और भी:

(var message, var count) = ("Hello", 4);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.