Using C # params keyword in generic type constructor

I have a generic class in C # with 2 constructors:

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

Building an object using int as a generic type and passing in two ints as arguments causes a call to the โ€œwrongโ€ constructor (from my point of view).

eg. Houses<int> houses = new Houses<int>(1,2) - calls the second constructor. Passing any other number of ints to the constructor will call the 1st constructor.

Is there a way around this otherwise than to remove the params keyword and make users pass an array of T when using the first constructor?

+6
source share
4 answers

A clearer solution is to have two static factory methods. If you put them in an inanimate class, you can also use conclusions like:

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

Call example:

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

Then your generic constructor does not need the "params" bit and there will be no confusion.

+13
source share

Perhaps instead of Params you can go to IEnumerable

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

The second constructor is a more exact match, which is the criterion used to evaluate the correctness of the constructor.

+2
source share

Given the following, since the original did not have too much class information, etc.

The compiler will decide that the new House (1,2) exactly matches the second constructor and uses it, please note that I took the answer with the most votes and it did not work.

 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 } } } 
+2
source share

All Articles