Практический пример, где Tuple можно использовать в .Net 4.0? - PullRequest
96 голосов
/ 30 апреля 2010

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

Ответы [ 19 ]

4 голосов
/ 30 апреля 2010

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

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

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

2 голосов
/ 01 сентября 2015

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

Не хочу сказать, что вы не должны использовать Tuple и это зло или что-то в этом роде, и яна сто процентов уверен, что есть некоторые задачи, где Tuple - лучший кандидат для использования, но, вероятно, вам следует подумать еще раз, действительно ли он вам нужен?

1 голос
/ 19 декабря 2014

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

Задача - написать ответ JSON от LINQ без каких-либо дополнительных классов:

 //I select some roles from my ORM my with subrequest and save results to Tuple list
 var rolesWithUsers = (from role in roles
                       select new Tuple<string, int, int>(
                         role.RoleName, 
                         role.RoleId, 
                         usersInRoles.Where(ur => ur.RoleId == role.RoleId).Count()
                      ));

 //Then I add some new element required element to this collection
 var tempResult = rolesWithUsers.ToList();
 tempResult.Add(new Tuple<string, int, int>(
                        "Empty", 
                         -1,
                         emptyRoleUsers.Count()
                      ));

 //And create a new anonimous class collection, based on my Tuple list
 tempResult.Select(item => new
            {
                GroupName = item.Item1,
                GroupId = item.Item2,
                Count = item.Item3
            });


 //And return it in JSON
 return new JavaScriptSerializer().Serialize(rolesWithUsers);

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

1 голос
/ 02 июля 2014

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

Другие простые альтернативы будут использовать параметр 'out'

private string MyMethod(out object)

или составление словаря

Dictionary<objectType1, objectType2>

Использование Tuple, однако, сохраняет либо создание объекта out, либо необходимость поиска записи в словаре;

1 голос
/ 23 января 2017

Ну, в моем случае мне пришлось использовать Tuple, когда я обнаружил, что мы не можем использовать параметр в асинхронном методе. Читайте об этом здесь . Мне также нужен был другой тип возврата. Поэтому я использовал Tuple вместо моего возвращаемого типа и пометил метод как асинхронный.

Пример кода ниже.

...
...
// calling code.
var userDetails = await GetUserDetails(userId);
Console.WriteLine("Username : {0}", userDetails.Item1);
Console.WriteLine("User Region Id : {0}", userDetails.Item2);
...
...

private async Tuple<string,int> GetUserDetails(int userId)
{
    return new Tuple<string,int>("Amogh",105);
    // Note that I can also use the existing helper method (Tuple.Create).
}

Подробнее о Tuple здесь . Надеюсь, это поможет.

0 голосов
/ 10 ноября 2017

Ну, я попробовал 3 способа решить ту же проблему в C # 7, и я нашел вариант использования для Tuples.

Работа с динамическими данными в веб-проектах иногда может быть затруднена при отображении и т. Д.

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

Такое ощущение, что DTO был создан бесплатно с помощью Tuple, и я могу получить доступ ко всем свойствам с помощью itemN, что больше похоже на статическую типизацию без необходимости создания отдельного DTO для этой цели.

using System;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var tuple = GetTuple();
            Console.WriteLine(tuple.Item1);
            Console.WriteLine(tuple.Item2);
            Console.WriteLine(tuple.Item3);
            Console.WriteLine(tuple);

            Console.WriteLine("---");

            var dyn = GetDynamic();
            Console.WriteLine(dyn.First);
            Console.WriteLine(dyn.Last);
            Console.WriteLine(dyn.Age);
            Console.WriteLine(dyn);

            Console.WriteLine("---");

            var arr = GetArray();
            Console.WriteLine(arr[0]);
            Console.WriteLine(arr[1]);
            Console.WriteLine(arr[2]);
            Console.WriteLine(arr);

            Console.Read();

            (string, string, int) GetTuple()
            {
                return ("John", "Connor", 1);
            }

            dynamic GetDynamic()
            {
                return new { First = "John", Last = "Connor", Age = 1 };
            }

            dynamic[] GetArray()
            {
                return new dynamic[] { "John", "Connor", 1 };
            }
        }
    }
}
0 голосов
/ 04 сентября 2017

Только для прототипирования - кортежи не имеют смысла. Их удобно использовать, но это только ярлык! За прототипы - отлично. Обязательно удалите этот код позже.

Легко писать, трудно читать. Он не имеет видимых преимуществ перед классами, внутренними классами, анонимными классами и т. Д.

0 голосов
/ 10 февраля 2015

Изменение формы объектов, когда вам нужно отправить их по проводу или передать в другой слой приложения, и несколько объектов объединяются в один:

Пример:

var customerDetails = new Tuple<Customer, List<Address>>(mainCustomer, new List<Address> {mainCustomerAddress}).ToCustomerDetails();

метод расширения:

public static CustomerDetails ToCustomerDetails(this Tuple<Website.Customer, List<Website.Address>> customerAndAddress)
    {
        var mainAddress = customerAndAddress.Item2 != null ? customerAndAddress.Item2.SingleOrDefault(o => o.Type == "Main") : null;
        var customerDetails = new CustomerDetails
        {
            FirstName = customerAndAddress.Item1.Name,
            LastName = customerAndAddress.Item1.Surname,
            Title = customerAndAddress.Item1.Title,
            Dob = customerAndAddress.Item1.Dob,
            EmailAddress = customerAndAddress.Item1.Email,
            Gender = customerAndAddress.Item1.Gender,
            PrimaryPhoneNo = string.Format("{0}", customerAndAddress.Item1.Phone)
        };

        if (mainAddress != null)
        {
            customerDetails.AddressLine1 =
                !string.IsNullOrWhiteSpace(mainAddress.HouseName)
                    ? mainAddress.HouseName
                    : mainAddress.HouseNumber;
            customerDetails.AddressLine2 =
                !string.IsNullOrWhiteSpace(mainAddress.Street)
                    ? mainAddress.Street
                    : null;
            customerDetails.AddressLine3 =
                !string.IsNullOrWhiteSpace(mainAddress.Town) ? mainAddress.Town : null;
            customerDetails.AddressLine4 =
                !string.IsNullOrWhiteSpace(mainAddress.County)
                    ? mainAddress.County
                    : null;
            customerDetails.PostCode = mainAddress.PostCode;
        }
...
        return customerDetails;
    }
0 голосов
/ 16 декабря 2015

Параметр out отлично подходит, когда нужно вернуть только несколько значений, но когда вы начинаете встречать 4, 5, 6 или более значений, которые должны быть возвращены, это может стать громоздким. Другой вариант возврата нескольких значений - создать и вернуть пользовательский класс / структура или использование кортежа для упаковки всех значений, которые необходимы должен быть возвращен методом.

Первый вариант, использующий класс / структуру для возврата значений, прост. Просто создайте тип (в данном примере это структура) примерно так:

public struct Dimensions
{
public int Height;
public int Width;
public int Depth;
}

Второй вариант, использующий кортеж, является еще более элегантным решением, чем использование пользовательских объект. Кортеж может быть создан для хранения любого числа значений различных типов. Кроме того, данные, которые вы храните в кортеже, являются неизменными; как только вы добавите данные в кортеж через конструктор или статический метод Create, эти данные не могут быть изменилось. Кортежи могут принимать до восьми различных значений. Если вам нужно вернуться более восьми значений, вам нужно будет использовать специальный класс Tuple: Класс Tuple При создании кортежа с более чем восемью значениями вы не можете использовать статический Create метод - вместо этого вы должны использовать конструктор класса. Вот как бы вы создать кортеж из 10 целых значений:

var values = new Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>> (
1, 2, 3, 4, 5, 6, 7, new Tuple<int, int, int> (8, 9, 10));

Конечно, вы можете продолжать добавлять больше кортежей в конец каждого встроенного кортежа, создание Tuple любого размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...