Utilizzo della parola chiave params C # in un costruttore di tipi generici
Domanda
Ho una classe generica in C # con 2 costruttori:
public Houses(params T[] InitialiseElements)
{}
public Houses(int Num, T DefaultValue)
{}
La costruzione di un oggetto usando int come tipo generico e passando due int come argomenti fa sì che il costruttore 'errato' venga chiamato (dal mio punto di vista).
es. Houses<int> houses = new Houses<int>(1,2)
- chiama il secondo costruttore. Passare qualsiasi altro numero di ints nel costruttore chiamerà il 1o costruttore.
Esiste un modo per aggirare questo se non rimuovere la parola chiave params e costringere gli utenti a passare un array di T quando usano il primo costruttore?
Soluzione
Una soluzione più chiara sarebbe quella di avere due metodi statici di fabbrica. Se li metti in una classe non generica, puoi anche beneficiare dell'inferenza di tipo:
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);
}
}
Esempio di chiamata:
Houses<string> x = Houses.CreateFromDefault(10, "hi");
Houses<int> y = Houses.CreateFromElements(20, 30, 40);
Quindi il costruttore del tuo tipo generico non ha bisogno del " params " un po 'e non ci sarà confusione.
Altri suggerimenti
Forse invece di Params potresti passare in IEnumerable
public Houses(IEnumerable<T> InitialiseElements){}
Il secondo costruttore è una corrispondenza più esatta , che è i criteri utilizzati per valutare quale costruttore è corretto.
Dato quanto segue poiché l'originale non aveva troppe informazioni sulla classe ecc.
Il compilatore deciderà esattamente che la nuova House (1,2) corrisponde esattamente al secondo costruttore e lo utilizzerà, nota che ho preso la risposta con il maggior numero di voti e non ha funzionato.
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
}
}
}