Mieux nommer dans les classes Tuple que “Item1”, “Item2”

Y a-t-il un moyen d’utiliser une classe Tuple, mais fournissez-y les noms des éléments?

Par exemple:

public Tuple GetOrderRelatedIds() 

Cela renvoie les ID pour OrderGroupId, OrderTypeId, OrderSubTypeId et OrderRequirementId.

Ce serait bien de faire savoir aux utilisateurs de ma méthode qui est qui. (Lorsque vous appelez la méthode, les résultats sont result.Item1, result.Item2, result.Item3, result.Item4. Il n’est pas clair lequel est lequel.)

(Je sais que je pourrais simplement créer une classe pour contenir tous ces ID, mais ceux-ci ont déjà leurs propres classes et créer une classe pour la valeur de retour de cette méthode semble idiot.)

Dans C # 7.0 (Visual Studio 2017), il existe une nouvelle construction pour cela:

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

Jusqu’à C # 7.0, il n’y avait aucun moyen de le faire sans définir votre propre type.

Voici une version trop compliquée de ce que vous demandez:

 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; } } } 

Pourquoi ne pas simplement faire un cours?

Avec .net 4, vous pourriez peut-être regarder ExpandoObject , mais ne l’utilisez pas pour ce cas simple car ce qui aurait été des erreurs de compilation deviendrait des erreurs d’exécution.

 class Program { static void Main(ssortingng[] 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. 

Quelque chose d’autre à mentionner est un type anonyme dans une méthode , mais vous devez créer une classe si vous voulez la renvoyer.

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

Si les types de vos objects sont tous différents, voici une classe que j’ai créée pour les obtenir de manière plus intuitive.

L’utilisation de cette classe:

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

Code source:

 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; } } } 

Non, vous ne pouvez pas nommer les membres du tuple.

L’entre-deux serait d’utiliser ExpandoObject au lieu de Tuple .

Pourquoi est-ce que tout le monde rend la vie si difficile? Les tuples sont destinés au traitement de données plutôt temporaire . Travailler avec Tuples tout le temps rendra le code très difficile à comprendre à un moment donné. Créer des classes pour tout peut éventuellement gonfler votre projet.

Il s’agit d’équilibre, cependant …

Votre problème semble être quelque chose que vous voudriez pour un cours. Et juste pour être complet, cette classe ci-dessous contient également des constructeurs.


Ceci est le modèle approprié pour

  • Un type de données personnalisé
    • sans plus de fonctionnalité. Les getters et setters peuvent également être étendus avec du code, obtenant / définissant des membres privés avec le modèle de nom de “_orderGroupId”, tout en exécutant également le code fonctionnel.
  • Y compris les constructeurs. Vous pouvez également choisir d’inclure un seul constructeur si toutes les propriétés sont obligatoires.
  • Si vous souhaitez utiliser tous les constructeurs, créer des bulles comme celle-ci est le modèle approprié pour éviter le code en double.

 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; } } 

Ou, si vous voulez vraiment simple: Vous pouvez également utiliser des initialiseurs de type:

 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; } 

Reproduire ma réponse à partir de cet article car il convient mieux ici.

À partir de C # v7.0, il est maintenant possible de nommer les propriétés de tuple utilisées par défaut pour les noms tels que Item2 , Item2 , etc.

Nommer les propriétés des littéraux tuple :

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

La sortie sur la console:

Nom – RBT_Yoga, Âge – 22 ans, Passion – Dosa

Renvoyer le tuple (ayant des propriétés nommées) à partir d’une méthode :

 static void Main(ssortingng[] args) { var empInfo = GetEmpInfo(); Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}"); } static (ssortingng firstName, ssortingng lastName, ssortingng 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); } 

La sortie sur la console:

Détails sur l’employé: Rasik, Bihari, Rasik-PC, 1000

Créer une liste de tuples ayant des propriétés nommées

 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}"); 

Sortie sur la console:

1 – vache 5 – poulets 1 – avion

J’espère avoir tout couvert. Au cas où, il y a quelque chose que j’ai manqué alors s’il vous plaît donnez-moi un retour dans les commentaires.

Remarque : Mes extraits de code utilisent la fonction d’interpolation de chaîne de C # v7, comme indiqué ici .

Je pense que je créerais une classe mais une autre alternative est les parameters de sortie.

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

Comme votre Tuple ne contient que des entiers, vous pouvez le représenter avec un Dictionary

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

mais je ne le recommande pas non plus.

J’écrirais les noms des objects dans le résumé. Ainsi, en survolant la fonction helloworld (), le texte indiquera hello = Item1 et world = Item2

  helloworld("Hi1,Hi2"); ///  /// Return hello = Item1 and world Item2 ///  /// ssortingng to split ///  private static Tuple helloworld(ssortingng 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’est très ennuyeux et je m’attends à ce que les futures versions de C # répondent à ce besoin. Je trouve que le travail le plus simple consiste à utiliser un type de structure de données différent ou à renommer les «éléments» pour votre santé mentale et pour la santé mentale des autres utilisateurs qui lisent votre code.

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

Vous pouvez écrire une classe contenant le Tuple.

Vous devez remplacer les fonctions Equals et GetHashCode

et les opérateurs == et! =.

 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(ssortingng[] 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)); } } 

reviendra:

Vrai

Vrai