C # 6 agrega una nueva característica solo para esto: extensión Agregar métodos. Esto siempre ha sido posible para VB.net, pero ahora está disponible en C #.
Ahora no tiene que agregar Add()
métodos a sus clases directamente, puede implementarlos como métodos de extensión. Al extender cualquier tipo enumerable con un Add()
método, podrá usarlo en expresiones de inicializador de colección. Para que ya no tenga que derivar explícitamente de las listas ( como se menciona en otra respuesta ), simplemente puede extenderlo.
public static class TupleListExtensions
{
public static void Add<T1, T2>(this IList<Tuple<T1, T2>> list,
T1 item1, T2 item2)
{
list.Add(Tuple.Create(item1, item2));
}
public static void Add<T1, T2, T3>(this IList<Tuple<T1, T2, T3>> list,
T1 item1, T2 item2, T3 item3)
{
list.Add(Tuple.Create(item1, item2, item3));
}
// and so on...
}
Esto le permitirá hacer esto en cualquier clase que implemente IList<>
:
var numbers = new List<Tuple<int, string>>
{
{ 1, "one" },
{ 2, "two" },
{ 3, "three" },
{ 4, "four" },
{ 5, "five" },
};
var points = new ObservableCollection<Tuple<double, double, double>>
{
{ 0, 0, 0 },
{ 1, 2, 3 },
{ -4, -2, 42 },
};
Por supuesto, no está restringido a extender colecciones de tuplas, puede ser para colecciones de cualquier tipo específico para el que desea la sintaxis especial.
public static class BigIntegerListExtensions
{
public static void Add(this IList<BigInteger> list,
params byte[] value)
{
list.Add(new BigInteger(value));
}
public static void Add(this IList<BigInteger> list,
string value)
{
list.Add(BigInteger.Parse(value));
}
}
var bigNumbers = new List<BigInteger>
{
new BigInteger(1), // constructor BigInteger(int)
2222222222L, // implicit operator BigInteger(long)
3333333333UL, // implicit operator BigInteger(ulong)
{ 4, 4, 4, 4, 4, 4, 4, 4 }, // extension Add(byte[])
"55555555555555555555555555555555555555", // extension Add(string)
};
C # 7 agregará soporte para las tuplas integradas en el lenguaje, aunque serán de un tipo diferente (en su System.ValueTuple
lugar). Por lo tanto, sería bueno agregar sobrecargas para las tuplas de valor para que también tenga la opción de usarlas. Desafortunadamente, no hay conversiones implícitas definidas entre los dos.
public static class ValueTupleListExtensions
{
public static void Add<T1, T2>(this IList<Tuple<T1, T2>> list,
ValueTuple<T1, T2> item) => list.Add(item.ToTuple());
}
De esta manera, la inicialización de la lista se verá aún mejor.
var points = new List<Tuple<int, int, int>>
{
(0, 0, 0),
(1, 2, 3),
(-1, 12, -73),
};
Pero en lugar de pasar por todos estos problemas, podría ser mejor cambiar a usar ValueTuple
exclusivamente.
var points = new List<(int, int, int)>
{
(0, 0, 0),
(1, 2, 3),
(-1, 12, -73),
};