Using C# params keyword in a constructor of generic types

混江龙づ霸主 提交于 2019-12-21 04:19:08

问题


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

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

Constructing an object using int as the generic type and passing in two ints as arguments causes the 'incorrect' constructor to be called (from my point of view).

E.g. Houses<int> houses = new Houses<int>(1,2) - calls the 2nd construtor. Passing in any other number of ints into the constructor will call the 1st constructor.

Is there any way around this other than removing the params keyword and forcing users to pass an array of T when using the first constructor?


回答1:


A clearer solution would be to have two static factory methods. If you put these into a nongeneric class, you can also benefit from type inference:

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

Example of calling:

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

Then your generic type's constructor doesn't need the "params" bit, and there'll be no confusion.




回答2:


Perhaps instead of Params you could pass in IEnumerable

public Houses(IEnumerable<T> InitialiseElements){}



回答3:


The 2nd constructor is a more exact match, which is the criteria used to evaluate which constructor is correct.




回答4:


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

The compiler is going to decide new House(1,2) matches the second constructor exactly and use that, notice that I took the answer with the most up 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
        }
    }
}


来源:https://stackoverflow.com/questions/213333/using-c-sharp-params-keyword-in-a-constructor-of-generic-types

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!