Using C# params keyword in a constructor of generic types

前端 未结 4 962
后悔当初
后悔当初 2021-02-14 20:42

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

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

Con

相关标签:
4条回答
  • 2021-02-14 21:02

    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
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-14 21:12

    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.

    0 讨论(0)
  • 2021-02-14 21:16

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

    0 讨论(0)
  • 2021-02-14 21:18

    Perhaps instead of Params you could pass in IEnumerable

    public Houses(IEnumerable<T> InitialiseElements){}
    
    0 讨论(0)
提交回复
热议问题