Эквиваленты C# 3.0 Кортежа (для бедных мужчин)

руководство

Python Его немного длинное обветренное иногда, но это говорит Вам всем, что необходимо знать для начинаний.

7
задан t3rse 30 November 2009 в 21:59
поделиться

7 ответов

Вы можете создавать анонимные типы, которые работают аналогично кортежам, но с полезными именами:

var itemsWithChildCounts 
    = myObjects.Select(x => new { Name = x.Name, Count = x.Children.Count() });
8
ответ дан 6 December 2019 в 21:14
поделиться

Вот код универсального кортежа, взятый из статьи Билла Вагнера в выпуске Visual Studio Magazine за апрель 2007 г.

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
}
5
ответ дан 6 December 2019 в 21:14
поделиться

Поскольку вы спрашивали мнение, я бы всегда создавать тип - я не могу понять, почему не делать этого.

Чаще всего вы можете обнаружить, что вам действительно нужен тип (основное использование - либо сохранить два элемента в коллекции, либо вернуть два элемента из вызова метода - в обоих случаях, если элементы не связаны между собой, вероятно, вы что-то делаете неправильно).

0
ответ дан 6 December 2019 в 21:14
поделиться

Для 1-2: я предпочитаю реализовать собственный класс кортежа. Украденная вами реализация - достойная. Он должен работать хорошо.

Для 3: Вот мое практическое правило - как только вы собираетесь повторно использовать эту функциональность в нескольких методах (с одними и теми же типами, имеющими то же значение), или если вы используете ее в любом общедоступном API, думаю, пора реализовать «настоящий» класс с вашими конкретными типами.

1
ответ дан 6 December 2019 в 21:14
поделиться

Мне не нравится вывод типов в C #, поскольку он слишком часто используется для более короткого написания. Конечно, это очень крутая функция, но люди злоупотребляют ею, ИМХО, как в этом случае.

В этом случае я бы явно указал тип, чтобы избежать путаницы по поводу типа (например, возможно, 42 - это длинный, или байт, или коротко).

Так почему бы не создать простой класс кортежей, который можно реализовать всего в несколько строк. А если вам лень, вы даже можете написать несколько методов расширения для своего класса кортежей. Это делает жизнь проще, но в то же время чище.

Не вижу смысла иметь "модный" кортежный класс вместо общего, представленного вами (за исключением вывода типа).

-2
ответ дан 6 December 2019 в 21:14
поделиться
  1. Метод «Реализация класса» настолько хорош, насколько это возможно (и в любом случае он должен быть в следующей версии .NET)
  2. Понятия не имею, я храню их в своем собственная личная библиотека классов на данный момент.
  3. Я бы подумал о создании для них подходящего класса, как только они станут доступны публике (т.е. когда они больше не используются только для хранения связанных значений для класса внутри).
0
ответ дан 6 December 2019 в 21:14
поделиться

I think it's good to create a new type when it makes sense to introduce a new value set into your program. For example, if you are writing a complex calculator, then make a complex number type. If you really just want to "glue" a few variables together for a moment, then a tuple is probably a better choice. Let's say you've got a simple function that gathers two numbers from the console... you might do something like:

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

I think it usually makes sense when a "getter" function has a return value but in this case it doesn't because I can't really have two return values. I could go and make a new type called TwoNumbers and use that but I think this quickly becomes more of a problem than a solution. If C# had tuples I may be able to do something like the following:

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

Now the really interesting question is: although C# doesn't have this feature am I able to implement it myself with a library? The code you suggest is a start but won't allow me to assign like I've done in the second example. I'm not sure about C# but you can get really darn close to this in C++ by using the fact that a function call can be the left operand to the assignment operator when it's return value is a reference type. Consider the following:

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

I'd say that is pretty darn close... instead of (x, y) = we have tie(x, y) =. If you are interested in implementation details, I'll refer you to the TR1 library where I first learned about this:

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

So to bring all this back to C# 3.0... we can certainly create a generic tuple class as you've shown, but can we create a function like tie to "unpack" the tuple in C#? I haven't tried it, sounds like fun. Without something like that, I'd be reluctant to let a C# tuple library proliferate through my code.

0
ответ дан 6 December 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: