Usando C # params palavra-chave em um construtor de tipos genéricos
Pergunta
Eu tenho uma classe genérica em C # com 2 construtores:
public Houses(params T[] InitialiseElements)
{}
public Houses(int Num, T DefaultValue)
{}
A construção de um objeto usando int como o tipo genérico e passando em dois ints como argumento faz com que o construtor 'incorreta' para ser chamado (do meu ponto de vista).
por exemplo. Houses<int> houses = new Houses<int>(1,2)
- chama a 2ª construtor. Passando em qualquer outro número de inteiros para o construtor irá chamar o primeiro construtor.
Existe alguma maneira de contornar isso diferente de remover os params palavra-chave e forçar os usuários a passar uma matriz de T ao usar o primeiro construtor?
Solução
Uma solução mais clara seria ter dois métodos de fábrica estáticos. Se você colocá-los em uma classe não genérica, você também pode se beneficiar do tipo de inferência:
public static class Houses
{
public static Houses<T> CreateFromElements<T>(params T[] initialElements)
{
return new Houses<T>(initialElements);
}
public Houses<T> CreateFromDefault<T>(int count, T defaultValue)
{
return new Houses<T>(count, defaultValue);
}
}
Exemplo de chamar:
Houses<string> x = Houses.CreateFromDefault(10, "hi");
Houses<int> y = Houses.CreateFromElements(20, 30, 40);
Em seguida, construtor do tipo genérico não precisa os "parâmetros" bit, e não haverá nenhuma confusão.
Outras dicas
Talvez em vez de Params você poderia passar em IEnumerable
public Houses(IEnumerable<T> InitialiseElements){}
O segundo construtor é a exata ??em> jogo mais, que é o critério utilizado para avaliar qual construtor está correto.
Dado o seguinte desde que o original não tinha muita informação sobre a classe etc.
O compilador vai decidir nova casa (1,2) corresponde ao segundo construtor exatamente eo uso que, aviso que eu tirei a resposta com as mais votos e não funcionou.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericTest
{
public class House<T>
{
public House(params T[] values)
{
System.Console.WriteLine("Params T[]");
}
public House(int num, T defaultVal)
{
System.Console.WriteLine("int, T");
}
public static House<T> CreateFromDefault<T>(int count, T defaultVal)
{
return new House<T>(count, defaultVal);
}
}
class Program
{
static void Main(string[] args)
{
House<int> test = new House<int>(1, 2); // prints int, t
House<int> test1 = new House<int>(new int[] {1, 2}); // prints parms
House<string> test2 = new House<string>(1, "string"); // print int, t
House<string> test3 = new House<string>("string", "string"); // print parms
House<int> test4 = House<int>.CreateFromDefault<int>(1, 2); // print int, t
}
}
}