O C # 6 adiciona um novo recurso apenas para isso: extension Adicione métodos. Isso sempre foi possível para o VB.net, mas agora está disponível em C #.
Agora você não precisa adicionar Add()
métodos diretamente às suas classes, pode implementá-los como métodos de extensão. Ao estender qualquer tipo enumerável com um Add()
método, você poderá usá-lo nas expressões do inicializador de coleção. Para que você não precise mais derivar explicitamente das listas ( como mencionado em outra resposta ), basta estendê-las.
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...
}
Isso permitirá que você faça isso em qualquer classe 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 },
};
É claro que você não está restrito a estender coleções de tuplas, pode ser para coleções de qualquer tipo específico para o qual você deseja a sintaxe 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)
};
O C # 7 adicionará suporte para tuplas criadas no idioma, embora elas sejam de um tipo diferente (em System.ValueTuple
vez disso). Portanto, seria bom adicionar sobrecargas para tuplas de valor, assim você tem a opção de usá-las também. Infelizmente, não há conversões implícitas definidas entre os dois.
public static class ValueTupleListExtensions
{
public static void Add<T1, T2>(this IList<Tuple<T1, T2>> list,
ValueTuple<T1, T2> item) => list.Add(item.ToTuple());
}
Dessa forma, a inicialização da lista ficará ainda melhor.
var points = new List<Tuple<int, int, int>>
{
(0, 0, 0),
(1, 2, 3),
(-1, 12, -73),
};
Mas, em vez de passar por todo esse problema, pode ser melhor mudar para o uso ValueTuple
exclusivo.
var points = new List<(int, int, int)>
{
(0, 0, 0),
(1, 2, 3),
(-1, 12, -73),
};