Pregunta

Tengo una clase genérica en C # con 2 constructores:

public Houses(params T[] InitialiseElements)
{}
public Houses(int Num, T DefaultValue)
{}

Construir un objeto usando int como el tipo genérico y pasar dos entradas como argumentos hace que se llame al constructor 'incorrecto' (desde mi punto de vista).

Por ejemplo. Houses<int> houses = new Houses<int>(1,2) - llama al segundo constructor. Al pasar cualquier otra cantidad de entradas al constructor, se llamará al 1er constructor.

¿Hay alguna forma de evitar esto además de eliminar la palabra clave params y obligar a los usuarios a pasar una matriz de T cuando usan el primer constructor?

¿Fue útil?

Solución

Una solución más clara sería tener dos métodos de fábrica estáticos. Si los coloca en una clase no genérica, también puede beneficiarse de la inferencia de tipos:

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

Ejemplo de llamada:

Houses<string> x = Houses.CreateFromDefault(10, "hi");
Houses<int> y = Houses.CreateFromElements(20, 30, 40);

Entonces el constructor de su tipo genérico no necesita " params " poco, y no habrá confusión.

Otros consejos

Quizás, en lugar de Parámetros, podría pasar en IEnumerable

public Houses(IEnumerable<T> InitialiseElements){}

El segundo constructor es una coincidencia más exacta , que es el criterio utilizado para evaluar qué constructor es el correcto.

Dado lo siguiente ya que el original no tenía demasiada información sobre la clase, etc.

El compilador decidirá que la nueva House (1,2) coincide exactamente con el segundo constructor y lo usará, tenga en cuenta que tomé la respuesta con la mayor cantidad de votos y no funcionó.

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
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top