Практический пример, где Кортеж может использоваться в.Net 4.0?

Я видел Кортеж, представленный в.Net 4, но я не могу вообразить, где он может использоваться. Мы можем всегда делать Пользовательский класс или Структуру.

97
задан Tim 24 November 2015 в 11:34
поделиться

7 ответов

В том-то и дело - удобнее , а не создавать собственный класс или структурировать все время. Это такое улучшение, как Action или Func ... вы можете создавать эти типы самостоятельно, но удобно, что они существуют во фреймворке.

83
ответ дан 24 November 2019 в 05:20
поделиться

В журнале MSDN есть отличная статья , в которой рассказывается о боли в животе и дизайнерских соображениях, которые вошел в добавление кортежа в BCL. Выбор между типом значения и ссылочным типом особенно интересен.

Как ясно из статьи, движущей силой Tuple было то, что многие группы внутри Microsoft использовали его, и команда F # была впереди. Хотя это не упоминается, я считаю, что новое ключевое слово «dynamic» в C # (и VB.NET) тоже имеет какое-то отношение к этому, кортежи очень распространены в динамических языках.

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


ОБНОВЛЕНИЕ: в связи с большой переработкой C # версии 7, теперь синтаксис стал намного популярнее. Предварительное объявление в этой записи блога .

26
ответ дан 24 November 2019 в 05:20
поделиться

Кортежи широко используются в функциональных языках которые могут делать с ними больше вещей, теперь F # является «официальным» языком .net, вы можете захотеть взаимодействовать с ним из C # и передавать их между кодом, написанным на двух языках.

5
ответ дан 24 November 2019 в 05:20
поделиться

Я использовал кортеж для решения Задачи 11 проекта Эйлер :

class Grid
{
    public static int[,] Cells = { { 08, 02, 22, // whole grid omitted

    public static IEnumerable<Tuple<int, int, int, int>> ToList()
    {
        // code converts grid to enumeration every possible set of 4 per rules
        // code omitted
    }
}

Теперь я могу решить всю проблему с помощью:

class Program
{
    static void Main(string[] args)
    {
        int product = Grid.ToList().Max(t => t.Item1 * t.Item2 * t.Item3 * t.Item4);
        Console.WriteLine("Maximum product is {0}", product);
    }
}

Я мог бы использовать для этого пользовательский тип, но он выглядел бы точно так же, как Tuple .

23
ответ дан 24 November 2019 в 05:20
поделиться

Синтаксис кортежа C# смехотворно громоздкий, поэтому кортежи больно объявлять. И у него нет сопоставления шаблонов, поэтому они также болезненны в использовании.

Но иногда вам просто нужна специальная группировка объектов без создания класса для нее. Например, предположим, что я хотел агрегировать список, но мне нужны два значения вместо одного:

// sum and sum of squares at the same time
var x =
    Enumerable.Range(1, 100)
    .Aggregate((acc, x) => Tuple.Create(acc.Item1 + x, acc.Item2 + x * x));

Вместо того, чтобы объединять коллекцию значений в один результат, давайте расширим один результат в коллекцию значений. Проще всего записать эту функцию:

static IEnumerable<T> Unfold<T, State>(State seed, Func<State, Tuple<T, State>> f)
{
    Tuple<T, State> res;
    while ((res = f(seed)) != null)
    {
        yield return res.Item1;
        seed = res.Item2;
    }
}

f преобразует некоторое состояние в кортеж. Возвращаем первое значение из кортежа и устанавливаем новое состояние на второе значение.Это позволяет нам сохранять состояние на протяжении всего вычисления.

Вы используете его как таковое:

// return 0, 2, 3, 6, 8
var evens =
    Unfold(0, state => state < 10 ? Tuple.Create(state, state + 2) : null)
    .ToList();

// returns 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
var fibs =
    Unfold(Tuple.Create(0, 1), state => Tuple.Create(state.Item1, Tuple.Create(state.Item2, state.Item1 + state.Item2)))
    .Take(10).ToList();

evens довольно просто, но fibs немного умнее. Его состояние на самом деле является кортежем, который содержит fib(n-2) и fib(n-1) соответственно.

16
ответ дан 24 November 2019 в 05:20
поделиться

Вот небольшой пример - скажем, у вас есть метод, который должен искать дескриптор и адрес электронной почты пользователя по идентификатору пользователя. Вы всегда можете создать собственный класс, содержащий эти данные, или использовать параметр ref / out для этих данных, или вы можете просто вернуть Tuple и получить красивую подпись метода без необходимости создавать новый POCO.

public static void Main(string[] args)
{
    int userId = 0;
    Tuple<string, string> userData = GetUserData(userId);
}

public static Tuple<string, string> GetUserData(int userId)
{
    return new Tuple<string, string>("Hello", "World");
}
23
ответ дан 24 November 2019 в 05:20
поделиться

Несколько примеров из моей головы:

  • Местоположение X и Y (и Z, если хотите)
  • Ширина и Высота
  • Все, что измеряется с течением времени

Например, вы бы не ' Я не хочу включать System.Drawing в веб-приложение только для использования Point / PointF и Size / SizeF.

4
ответ дан 24 November 2019 в 05:20
поделиться