Intereting Posts
Взаимодействие октавы с C # Создание пользовательского интерфейса для мониторинга и взаимодействия с работающей службой Windows Как использовать PasswordBox как TextBox? ASP.net MVC – пользовательский фильтр HandleError – укажите представление на основе типа исключения Как настроить DataGridView ComboBoxColumn с другим источником данных в каждой ячейке? Как навсегда отключить региональную фальцовку в Visual Studio 2008 Как написатьAllLines в C # без CRLF Развязка ASP.NET MVC 5 Идентификация, позволяющая реализовать многоуровневое приложение Как проверить, перегружает ли тип / поддерживает определенный оператор? Как изменить цвет подсветки System.Windows.Forms.ToolStripButton при выборе? Итерация над пикселями изображения и поворот Цвета Использование NLog в качестве регистратора файлов опрокидывания Подключение C # к Oracle Как исправить кодировку UTF для пробелов? VB.NET WithEvents поведение ключевого слова – ограничение компилятора VB.NET?

Лучше называть в classах Tuple, чем «Item1», «Item2»

Есть ли способ использовать class Tuple, но укажите имена элементов в нем?

Например:

public Tuple GetOrderRelatedIds() 

Это возвращает идентификаторы для OrderGroupId, OrderTypeId, OrderSubTypeId и OrderRequirementId.

Было бы неплохо сообщить пользователям моего метода, что есть. (Когда вы вызываете метод, результатом являются результат. Результат 1, result.Item2, result.Item3, result.Item4. Неясно, какой из них является.)

(Я знаю, что могу просто создать class для хранения всех этих идентификаторов, но у этих идентификаторов уже есть свои собственные classы, в которых они живут, и создание classа для возвращаемого значения этого метода кажется глупым.)

    В C # 7.0 (Visual Studio 2017) для этого есть новая конструкция:

     (string first, string middle, string last) LookupName(long id) 

    До C # 7.0 не было никакого способа сделать это, чтобы определить свой собственный тип.

    Вот чересчур сложная версия того, что вы спрашиваете:

     class MyTuple : Tuple { public MyTuple(int one, int two) :base(one, two) { } public int OrderGroupId { get{ return this.Item1; } } public int OrderTypeId { get{ return this.Item2; } } } 

    Почему бы просто не сделать class?

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

     class Program { static void Main(string[] args) { dynamic employee, manager; employee = new ExpandoObject(); employee.Name = "John Smith"; employee.Age = 33; manager = new ExpandoObject(); manager.Name = "Allison Brown"; manager.Age = 42; manager.TeamSize = 10; WritePerson(manager); WritePerson(employee); } private static void WritePerson(dynamic person) { Console.WriteLine("{0} is {1} years old.", person.Name, person.Age); // The following statement causes an exception // if you pass the employee object. // Console.WriteLine("Manages {0} people", person.TeamSize); } } // This code example produces the following output: // John Smith is 33 years old. // Allison Brown is 42 years old. 

    Что-то еще заслуживающее упоминания является анонимным типом для метода , но вам нужно создать class, если вы хотите его вернуть.

     var MyStuff = new { PropertyName1 = 10, PropertyName2 = "string data", PropertyName3 = new ComplexType() }; 

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

    Использование этого classа:

     var t = TypedTuple.Create("hello", 1, new MyClass()); var s = t.Get(); var i = t.Get(); var c = t.Get(); 

    Исходный код:

     public static class TypedTuple { public static TypedTuple Create(T1 t1) { return new TypedTuple(t1); } public static TypedTuple Create(T1 t1, T2 t2) { return new TypedTuple(t1, t2); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3) { return new TypedTuple(t1, t2, t3); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3, T4 t4) { return new TypedTuple(t1, t2, t3, t4); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { return new TypedTuple(t1, t2, t3, t4, t5); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { return new TypedTuple(t1, t2, t3, t4, t5, t6); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { return new TypedTuple(t1, t2, t3, t4, t5, t6, t7); } public static TypedTuple Create(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { return new TypedTuple(t1, t2, t3, t4, t5, t6, t7, t8); } } public class TypedTuple { protected Dictionary items = new Dictionary(); public TypedTuple(T item1) { Item1 = item1; } public TSource Get() { object value; if (this.items.TryGetValue(typeof(TSource), out value)) { return (TSource)value; } else return default(TSource); } private T item1; public T Item1 { get { return this.item1; } set { this.item1 = value; this.items[typeof(T)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2) : base(item1) { Item2 = item2; } private T2 item2; public T2 Item2 { get { return this.item2; } set { this.item2 = value; this.items[typeof(T2)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3) : base(item1, item2) { Item3 = item3; } private T3 item3; public T3 Item3 { get { return this.item3; } set { this.item3 = value; this.items[typeof(T3)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4) : base(item1, item2, item3) { Item4 = item4; } private T4 item4; public T4 Item4 { get { return this.item4; } set { this.item4 = value; this.items[typeof(T4)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) : base(item1, item2, item3, item4) { Item5 = item5; } private T5 item5; public T5 Item5 { get { return this.item5; } set { this.item5 = value; this.items[typeof(T5)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) : base(item1, item2, item3, item4, item5) { Item6 = item6; } private T6 item6; public T6 Item6 { get { return this.item6; } set { this.item6 = value; this.items[typeof(T6)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) : base(item1, item2, item3, item4, item5, item6) { Item7 = item7; } private T7 item7; public T7 Item7 { get { return this.item7; } set { this.item7 = value; this.items[typeof(T7)] = value; } } } public class TypedTuple : TypedTuple { public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) : base(item1, item2, item3, item4, item5, item6, item7) { Item8 = item8; } private T8 item8; public T8 Item8 { get { return this.item8; } set { this.item8 = value; this.items[typeof(T8)] = value; } } } 

    Нет, вы не можете назвать членов кортежа.

    В промежутке будет использовать ExpandoObject вместо Tuple.

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

    Начиная с C # v7.0 теперь можно назвать свойства кортежа, которые ранее использовались по умолчанию для таких имен, как Item1 , Item2 и т. Д.

    Именование свойств экземпляров Tuple :

     var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa"); Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}"); 

    Выход на консоли:

    Название – RBT_Yoga, Возраст – 22, Страсть – Доса

    Возвращаемый кортеж (с именами свойств) из метода :

     static void Main(string[] args) { var empInfo = GetEmpInfo(); Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}"); } static (string firstName, string lastName, string computerName, int Salary) GetEmpInfo() { //This is hardcoded just for the demonstration. Ideally this data might be coming from some DB or web service call return ("Rasik", "Bihari", "Rasik-PC", 1000); } 

    Выход на консоли:

    Сведения о сотрудниках: Rasik, Bihari, Rasik-PC, 1000

    Создание списка кортежей с именованными свойствами

     var tupleList = new List< (int Index, string Name)> { (1, "cow"), (5, "chickens"), (1, "airplane") }; foreach (var tuple in tupleList) Console.WriteLine($"{tuple.Index} - {tuple.Name}"); 

    Выход на консоли:

    1 – корова 5 – куры 1 – самолет

    Надеюсь, я все покрыл. В случае, если есть что-то, что я пропустил, пожалуйста, дайте мне отзыв в комментариях.

    Примечание . В моих fragmentах кода используется функция строковой интерполяции C # v7, как описано здесь .

    Я думаю, что я бы создал class, но другой альтернативой являются выходные параметры.

     public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId) 

    Так как ваш Tuple содержит только целые числа, вы можете представить его с помощью Dictionary

     var orderIds = new Dictionary { {"OrderGroupId", 1}, {"OrderTypeId", 2}, {"OrderSubTypeId", 3}, {"OrderRequirementId", 4}. }; 

    но я тоже этого не рекомендую.

    Почему каждый делает жизнь так тяжело. Кортежи предназначены для довольно временной обработки данных . Работа с кортежами все время заставит код очень трудно понять в какой-то момент. Создание classов для всего может в конечном итоге раздуть ваш проект.

    Это баланс, однако …

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


    Это правильный шаблон для

    • Пользовательский тип данных
      • без дополнительной функциональности. Геттеры и сеттеры также могут быть расширены с помощью кода, получения / установки частных членов с шаблоном имен «_orderGroupId», а также выполнения функционального кода.
    • Включая конструкторы. Вы также можете включить только один конструктор, если все свойства являются обязательными.
    • Если вы хотите использовать все конструкторы, пузырьки подобны этому правильному шаблону, чтобы избежать дублирования кода.

     public class OrderRelatedIds { public int OrderGroupId { get; set; } public int OrderTypeId { get; set; } public int OrderSubTypeId { get; set; } public int OrderRequirementId { get; set; } public OrderRelatedIds() { } public OrderRelatedIds(int orderGroupId) : this() { OrderGroupId = orderGroupId; } public OrderRelatedIds(int orderGroupId, int orderTypeId) : this(orderGroupId) { OrderTypeId = orderTypeId; } public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId) : this(orderGroupId, orderTypeId) { OrderSubTypeId = orderSubTypeId; } public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId, int orderRequirementId) : this(orderGroupId, orderTypeId, orderSubTypeId) { OrderRequirementId = orderRequirementId; } } 

    Или, если вы хотите, чтобы это было очень просто: вы также можете использовать инициализаторы типов:

     OrderRelatedIds orders = new OrderRelatedIds { OrderGroupId = 1, OrderTypeId = 2, OrderSubTypeId = 3, OrderRequirementId = 4 }; public class OrderRelatedIds { public int OrderGroupId; public int OrderTypeId; public int OrderSubTypeId; public int OrderRequirementId; } 

    Я бы написал имена элементов в сумме. Поэтому, наведя над функцией helloworld (), в тексте будет сказано hello = Item1 и world = Item2

      helloworld("Hi1,Hi2"); ///  /// Return hello = Item1 and world Item2 ///  /// string to split ///  private static Tuple helloworld(string input) { bool hello = false; bool world = false; foreach (var hw in input.Split(',')) { switch (hw) { case "Hi1": hello= true; break; case "Hi2": world= true; break; } } return new Tuple(hello, world); } 

    Это очень раздражает, и я ожидаю, что будущие версии C # помогут решить эту проблему. Я считаю, что самая простая работа – либо использовать другой тип структуры данных, либо переименовывать «элементы» для вашего здравомыслия и для здравого смысла других, читающих ваш код.

     Tuple result = await SendApiRequest(); ApiResource apiResource = result.Item1; JSendResponseStatus jSendStatus = result.Item2; 

    Вы можете написать class, содержащий Tuple.

    Вам необходимо переопределить функции Equals и GetHashCode

    и операторы == и! =.

     class Program { public class MyTuple { private Tuple t; public MyTuple(int a, int b) { t = new Tuple(a, b); } public int A { get { return t.Item1; } } public int B { get { return t.Item2; } } public override bool Equals(object obj) { return t.Equals(((MyTuple)obj).t); } public override int GetHashCode() { return t.GetHashCode(); } public static bool operator ==(MyTuple m1, MyTuple m2) { return m1.Equals(m2); } public static bool operator !=(MyTuple m1, MyTuple m2) { return !m1.Equals(m2); } } static void Main(string[] args) { var v1 = new MyTuple(1, 2); var v2 = new MyTuple(1, 2); Console.WriteLine(v1 == v2); Dictionary d = new Dictionary(); d.Add(v1, 1); Console.WriteLine(d.ContainsKey(v2)); } } 

    вернусь:

    Правда

    Правда