سؤال

انا مهتم:ما هو التناظرية لـ C#؟ std::pair في C++؟وجدت System.Web.UI.Pair فئة، لكنني أفضل شيئًا يعتمد على القالب.

شكرًا لك!

هل كانت مفيدة؟

المحلول

تتوفر

منذ .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

نصائح أخرى

System.Web.UI تحتوي على Pair لأنه تم استخدامه بكثافة في ASP.NET 1.1 كبنية ViewState داخلية.

تحديث أغسطس 2017: يوفر C# 7.0 / .NET Framework 4.7 بناء جملة للإعلان عن Tuple مع العناصر المسماة باستخدام الأمر 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 لقد أصبحت جزءًا من .NET منذ الإصدار 4.0.

هنا مقالة سابقة تصف التضمين في .NET4.0 ودعم الأدوية الجنيسة:

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

ولسوء الحظ، هناك لا شيء. يمكنك استخدام System.Collections.Generic.KeyValuePair<K, V> في كثير من الحالات.

وبدلا من ذلك، يمكنك استخدام أنواع غير معروفة للتعامل مع الصفوف، على الأقل محليا:

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

والبديل الأخير هو لإنشاء دراسي الخاصة.

الصفوف اعتبارا من الإصدار 4.0.

بعض الإجابات تبدو خاطئة،

  1. لا يمكنك استخدام القاموس لكيفية تخزين الأزواج (a,b) و(a,c).لا ينبغي الخلط بين مفهوم الأزواج وبين البحث النقابي عن المفاتيح والقيم
  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));
    }
}

إذا حان القواميس وما شابه ذلك، كنت تبحث عن System.Collections.Generic.KeyValuePair .

واعتمادا على ما تريد تحقيقه، قد ترغب في محاولة الخروج KeyValuePair .

والحقيقة أنه لا يمكنك تغيير مفتاح إدخال يمكن بالطبع تصحيحه عن طريق استبدال ببساطة دخول كامل من قبل مثيل جديد من KeyValuePair.

وأنا خلقت C # تنفيذ التيوبل، الذي يحل المشكلة بشكل عام لمدة تتراوح بين سنتين وخمس القيم - <وأ href = "http://shadowcoding.blogspot.com/2008/12/tuples.html" يختلط = "نوفولو noreferrer "> وهنا بلوق وظيفة ، الذي يحتوي على وصلة إلى المصدر.

وكنت أسأل نفس السؤال الآن فقط بعد جوجل سريعة وجدت أن هناك فئة الزوج في. NET إلا في وSystem.Web.UI ^ ~ ^ (<لأ href = "HTTP: // MSDN. microsoft.com/en-us/library/system.web.ui.pair.aspx "يختلط =" نوفولو noreferrer "> <لأ href =" http://msdn.microsoft.com/en-us/ مكتبة / system.web.ui.pair.aspx "يختلط =" نوفولو noreferrer "> http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) الله يعلم لماذا وضعوا هناك بدلا من إطار مجموعات

ومنذ NET 4.0 لديك الدرجة System.Tuple<T1, T2>:

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

وأنا عادة توسيع الطبقة 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);

في أجل الحصول على ما سبق للعمل (أنا في حاجة إلى زوج كمفتاح من القاموس). كان لي أن أضيف:

    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();
    }

ولقمع تحذير المترجم.

والمكتبة PowerCollections (متوفرة سابقا من Wintellect لكن استضافت الآن على كود بلاكس @ http://powercollections.codeplex.com ) لديها بنية الزوج عام.

وبصرف النظر عن فئة مخصصة أو صافي 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);
scroll top