سؤال

أجد نفسي أحيانا في C# 3.0 تبحث عن طرق لمحاكاة مفهوم tuple.مع مرور الوقت لقد كان مختلف "الرجل الفقير" تطبيقات, وهنا بعض منها:

الأساسية كائن مجموعة:

object[] poorTuple = new object[]{foo,bar,baz}; // basic object array

أكثر بقوة كتبته, HoHoHo...

KeyValuePair<TypeA, KeyValuePair<TypeB, TypeC>> poorTuple;

تنفيذ فئة يمكن استخدام نوع الاستدلال (رفعت من البرمجة الوظيفية عن العالم الحقيقي)

public static class Tuple{
  public static Tuple<T1, T2> Create<T1 foo, T2 bar>{
    return new Tuple<T1, T2>(foo, bar);
  }
}
// later: 
var data = Tuple.Create("foo", 42);

الأسئلة:

  1. أي طرق أخرى إلى الرجل الفقير tuple في C# 3.0 (أو اللغة المفضلة التي تفتقر إلى بنية البيانات).

  2. ما هو أفضل طريقة للحصول على tuple في C# 3.0 - إذا كان أي شخص لديه مكتبة التوصية هو موضع ترحيب.

  3. في نقطة ما (نعم التعميم بالنسبة لي) لا معنى لخلق نوع معين بدلا من شيء مثل قائمة أو tuple?(يبحث عن القواعد من الإبهام)

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

المحلول

يمكنك إنشاء مجهول الأنواع التي تعمل على نحو مماثل الصفوف إلا مع أسماء مفيدة:

var itemsWithChildCounts 
    = myObjects.Select(x => new { Name = x.Name, Count = x.Children.Count() });

نصائح أخرى

هنا هو رمز عامة tuple مأخوذة من قانون واغنر المادة في نيسان / أبريل 2007 الطبعة Visual Studio مجلة.

public struct Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
{
    private readonly T1 first;
    public T1 First
    {
        get { return first; }
    }

    private readonly T2 second;
    public T2 Second
    {
        get { return second; }
    } 

    public Tuple(T1 f, T2 s)
    {
        first = f;
        second = s;
    }

    #region IEquatable<Tuple<T1,T2>> Members
    public bool Equals(Tuple<T1, T2> other)
    {
        return first.Equals(other.first) && 
            second.Equals(other.second);
    }

    public override bool Equals(object obj)
    {
        if (obj is Tuple<T1, T2>)
            return this.Equals((Tuple<T1, T2>)obj);
        else
            return false;
    }

    public override int GetHashCode()
    {
        return first.GetHashCode() ˆ second.GetHashCode();
    }
    #endregion
}

1 - 2:أنا أفضل تنفيذ الخاص بك tuple الدرجة.تنفيذ سرقت هو واحد لائق.يجب أن تعمل بشكل جيد.

3:هنا هو بلدي القاعدة - في أقرب وقت كما كنت ذاهب إلى إعادة استخدام هذه الوظيفة في أساليب متعددة (مع نفس الأنواع لها نفس المعنى) ، أو إذا كنت تستخدم في أي API العامة, أعتقد أنه حان الوقت لتنفيذ "الحقيقي" الطبقة مع أنواع محددة.

  1. إن "تنفيذ فئة" طريقة جيدة كما انها سوف تحصل على (وينبغي أن يكون في النسخة القادمة من .صافي على أي حال)
  2. لا أدري فأنا الاحتفاظ بها في المكتبة الشخصية من فصول الآن.
  3. لفكرت في السليم فئة لهم في أقرب وقت لأنها تحصل يتعرض للجمهور (أيعندما لم تعد تستخدم فقط لتخزين ذات قيم الطبقة داخليا).

بما أنك طلبت رأي لي أن يكون دائما خلق نوع--أنا لا يمكن معرفة السبب.

في كثير من الأحيان لا يمكن أن تجد أن كنت في الواقع في حاجة إلى نوع (الاستخدام الرئيسي هو إما لتخزين اثنين من العناصر في مجموعة أو العودة بندين من استدعاء الأسلوب-في كل الحالات إذا كانت العناصر ليست ارتباطا وثيقا ، ربما كنت تفعل شيئا خاطئا).

أعتقد أنه من الجيد أن خلق نوع جديد عندما المنطقي إدخال قيمة جديدة مجموعة في البرنامج.على سبيل المثال ، إذا كنت تكتب مجمع آلة حاسبة, ثم جعل معقدة نوع الرقم.إذا كنت حقا ترغب فقط في "الغراء" بعض المتغيرات معا للحظة ، ثم tuple هو على الأرجح أفضل خيار.دعونا نقول كنت قد حصلت على وظيفة بسيطة تجمع رقمين من وحدة...قد تفعل شيئا مثل:

static void GetNumbers(out int x, out int y) { ... }
...
int x, y;
GetNumbers(out x, out y);

أعتقد أنه عادة ما يجعل الشعور عندما "حاصل" الدالة قيمة الإرجاع ولكن في هذه الحالة لا لأنني لا أستطيع حقا اثنين من عودة القيم.أنا يمكن أن تجعل نوع جديد يسمى TwoNumbers واستخدام ذلك ولكن أعتقد أن هذا سرعان ما يصبح مشكلة وليس حلا.إذا كان C# كانت الصفوف قد تكون قادرة على القيام بشيء من هذا القبيل ما يلي:

static (int, int) GetNumbers() { ... }
...
int x, y;
(x, y) = GetNumbers();

الآن السؤال المثير للاهتمام حقا هو:على الرغم من أن C# لا تملك هذه الميزة هل أنا قادرة على تنفيذ ذلك بنفسي مع المكتبة ؟ رمز تقترح بداية ولكن لن اسمحوا لي أن تعيين مثل ما فعلت في المثال الثاني.أنا لست متأكدة من C# ولكن يمكنك الحصول على حقا الرتق على مقربة من هذا في C++ باستخدام حقيقة أن استدعاء دالة يمكن المعامل الأيسر إلى عامل التعيين عندما يكون قيمة الإرجاع هي نوع مرجع.النظر في ما يلي:

// this class is implemented much like yours only with C++
template<typename T1, typename T2> class tuple { ... }
...
template<typename T1, typename T2> tuple<T1, T2>& tie(T1 a, T2 b) { ... }
...
template<typename T1, typename T2> tuple<T1, T2> get_numbers() { ... }
...
int x, y;
tie(x, y) = get_numbers();

أود أن أقول هذا هو قريبين...بدلا من (x, y) = لدينا tie(x, y) =.إذا كنت مهتما في تفاصيل التنفيذ ، سوف أشير لك إلى TR1 المكتبة حيث علمت لأول مرة عن هذا:

http://www.boost.org/doc/libs/1_41_0/libs/tuple/doc/tuple_users_guide.html#tiers

حتى جلب كل هذا الى C# 3.0...ونحن بالتأكيد يمكن أن تخلق عام tuple الطبقة كما هو موضح ، ولكن يمكننا إنشاء دالة مثل التعادل إلى "فك" tuple في C# ؟ لم أحاول ذلك ، يبدو وكأنه متعة.دون شيء من هذا القبيل ، سأكون مترددة في السماح C# tuple مكتبة تتكاثر من خلال قانون بلدي.

أنا لا أحب نوع الاستدلال في C# لأنه أساء إلى الكثير من أقصر الكتابة.وبطبيعة الحال هي سمة باردة جدا ، ولكن الناس الاعتداء عليه IMHO في مثل هذه الحالة.

في هذه الحالة أود أن يحدد نوع صراحة لتجنب التباسات حول نوع (أيربما 42 طويلة ، أو بايت أو قصيرة).

فلماذا لا وجود بسيطة tuple الدرجة التي يمكن تنفيذها في بضعة أسطر.و إذا كنت كسول يمكنك حتى كتابة بعض طرق الإرشاد الخاص بك tuple الدرجة.هذا يجعل الحياة أسهل ولكن أيضا أكثر نظافة.

لا أرى فائدة من وجود "الهوى" tuple فئة بدلا من عام واحد قدم (باستثناء نوع الاستدلال).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top