tuple dotnetperls c# c#-4.0 tuples

tuple c# dotnetperls



Mejor denominaciĆ³n en clases Tuple que "Item1", "Item2" (11)

¿Por qué todos hacen la vida tan difícil? Las tuplas son para el procesamiento de datos más bien temporal . Trabajar con Tuples todo el tiempo hará que el código sea muy difícil de entender en algún momento. Crear clases para todo eventualmente podría hinchar su proyecto.

Se trata de equilibrio, sin embargo ...

Tu problema parece ser algo por lo que querrías una clase. Y para completar, esta clase a continuación también contiene constructores.

Este es el patrón apropiado para

  • Un tipo de datos personalizado
    • sin más funcionalidades Getters y setters también se pueden expandir con código, obteniendo / configurando miembros privados con el patrón de nombre de "_orderGroupId", mientras también se ejecuta el código funcional.
  • Incluyendo constructores. También puede optar por incluir solo un constructor si todas las propiedades son obligatorias.
  • Si desea utilizar todos los constructores, burbujear de esta manera es el patrón adecuado para evitar el código duplicado.

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

O, si lo desea, es realmente simple: también puede usar los inicializadores de tipo:

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

¿Hay alguna manera de usar una clase Tuple, pero suministrar los nombres de los elementos en ella?

Por ejemplo:

public Tuple<int, int, int int> GetOrderRelatedIds()

Eso devuelve los id para OrderGroupId, OrderTypeId, OrderSubTypeId y OrderRequirementId.

Sería bueno dejar que los usuarios de mi método sepan cuál es cuál. (Cuando llama al método, los resultados son result.Item1, result.Item2, result.Item3, result.Item4. No está claro cuál es cuál).

(Sé que podría crear una clase para guardar todos estos ID, pero estos ID ya tienen sus propias clases en las que viven y hacer una clase para el valor de retorno de este método parece tonto).


Aquí hay una versión demasiado complicada de lo que está preguntando:

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

¿Por qué no solo hacer una clase?


Con .net 4 podría ver el ExpandoObject , sin embargo, no lo use para este caso simple, ya que los errores en tiempo de compilación se convertirían en errores de tiempo de ejecución.

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.

Algo más que vale la pena mencionar es un tipo anónimo dentro de un método , pero debe crear una clase si desea devolverlo.

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


Creo que crearía una clase, pero otra alternativa son los parámetros de salida.

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

Como tu Tuple solo contiene enteros, puedes representarlo con un Dictionary<string,int>

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

pero tampoco lo recomiendo.


En C # 7.0 (Visual Studio 2017) hay una nueva construcción para hacer eso:

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


Escribiría los nombres de los elementos en el resumen ... así que al pasar el ratón sobre la función helloworld () el texto dirá hello = Item1 y world = Item2

`helloworld (" Hi1, Hi2 ");

/// <summary> /// Return hello = Item1 and world Item2 /// </summary> /// <param name="input">string to split</param> /// <returns></returns> private static Tuple<bool, bool> 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<bool, bool>(hello, world); }`


Esto es muy molesto y espero que las versiones futuras de C # aborden esta necesidad. Encuentro que el trabajo más fácil consiste en utilizar un tipo de estructura de datos diferente o cambiar el nombre de los "elementos" por su cordura y por la cordura de los demás que leen su código.

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


No, no hay una manera de hacer esto sin definir tu propio tipo.


No, no puedes nombrar a los miembros de la tupla.

El intermedio sería usar ExpandoObject lugar de Tuple.


Puede escribir una clase que contenga la Tupla.

Debe anular las funciones Equals y GetHashCode

y los operadores == y! =.

class Program { public class MyTuple { private Tuple<int, int> t; public MyTuple(int a, int b) { t = new Tuple<int, int>(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<MyTuple, int> d = new Dictionary<MyTuple, int>(); d.Add(v1, 1); Console.WriteLine(d.ContainsKey(v2)); } }

volverá:

Cierto

Cierto


Si los tipos de tus artículos son todos diferentes, aquí hay una clase que hice para que sean más intuitivos.

El uso de esta clase:

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

Código fuente:

public static class TypedTuple { public static TypedTuple<T1> Create<T1>(T1 t1) { return new TypedTuple<T1>(t1); } public static TypedTuple<T1, T2> Create<T1, T2>(T1 t1, T2 t2) { return new TypedTuple<T1, T2>(t1, t2); } public static TypedTuple<T1, T2, T3> Create<T1, T2, T3>(T1 t1, T2 t2, T3 t3) { return new TypedTuple<T1, T2, T3>(t1, t2, t3); } public static TypedTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4) { return new TypedTuple<T1, T2, T3, T4>(t1, t2, t3, t4); } public static TypedTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { return new TypedTuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5); } public static TypedTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { return new TypedTuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6); } public static TypedTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { return new TypedTuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7); } public static TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> Create<T1, T2, T3, T4, T5, T6, T7, T8>(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>(t1, t2, t3, t4, t5, t6, t7, t8); } } public class TypedTuple<T> { protected Dictionary<Type, object> items = new Dictionary<Type, object>(); public TypedTuple(T item1) { Item1 = item1; } public TSource Get<TSource>() { 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<T1, T2> : TypedTuple<T1> { 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<T1, T2, T3> : TypedTuple<T1, T2> { 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<T1, T2, T3, T4> : TypedTuple<T1, T2, T3> { 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<T1, T2, T3, T4, T5> : TypedTuple<T1, T2, T3, T4> { 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<T1, T2, T3, T4, T5, T6> : TypedTuple<T1, T2, T3, T4, T5> { 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<T1, T2, T3, T4, T5, T6, T7> : TypedTuple<T1, T2, T3, T4, T5, T6> { 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<T1, T2, T3, T4, T5, T6, T7, T8> : TypedTuple<T1, T2, T3, T4, T5, T6, T7> { 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; } } }