2008-10-17 8 views
6

j'ai une classe générique en C# avec 2 constructeurs:en utilisant C# params mot-clé dans un constructeur de types génériques

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

Construire un objet en utilisant un int comme type générique et passant dans deux ints comme arguments provoque la ' constructeur incorrect à appeler (de mon point de vue).

E.g. Houses<int> houses = new Houses<int>(1,2) - appelle le 2ème construtor. Passer dans un autre nombre d'ints dans le constructeur appellera le 1er constructeur.

Existe-t-il une autre solution que de supprimer le mot-clé params et de forcer les utilisateurs à passer un tableau de T lors de l'utilisation du premier constructeur?

Répondre

13

Une solution plus claire serait d'avoir deux méthodes d'usine statiques. Si vous mettez les dans une classe non générique, vous pouvez également bénéficier de l'inférence de type:

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

Exemple d'appel:

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

Ensuite, le constructeur de votre type générique n'a pas besoin du bit « params », et il n'y aura pas de confusion.

2

Peut-être au lieu de Params vous pourriez passer à IEnumerable

public Houses(IEnumerable<T> InitialiseElements){} 
2

Le 2ème constructeur est une plus correspondance exacte, qui est les critères utilisés pour évaluer quel constructeur est correct.

2

Compte tenu de ce qui suit depuis l'original n'a pas eu trop d'informations sur la classe, etc.

Le compilateur va décider nouvelle maison (1,2) correspond au second constructeur exactement et l'utiliser, notez que je a pris la réponse avec le plus de votes et cela n'a pas fonctionné.

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 
     } 
    } 
} 
Questions connexes