ジェネリック型のコンストラクターでC#paramsキーワードを使用する

StackOverflow https://stackoverflow.com/questions/213333

  •  03-07-2019
  •  | 
  •  

質問

2つのコンストラクターを持つC#のジェネリッククラスがあります:

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

ジェネリック型としてintを使用し、引数として2つのintを渡すことでオブジェクトを構築すると、「誤った」コンストラクターが呼び出されます(私の観点から)。

E.g。 Houses<int> houses = new Houses<int>(1,2)-2番目のコンストラクターを呼び出します。他の数のintをコンストラクターに渡すと、最初のコンストラクターが呼び出されます。

paramsキーワードを削除し、最初のコンストラクターを使用するときにユーザーにTの配列を強制的に渡す以外に、これを回避する方法はありますか?

役に立ちましたか?

解決

より明確な解決策は、2つの静的ファクトリメソッドを持つことです。これらを非ジェネリッククラスに入れると、型推論の恩恵を受けることもできます。

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

呼び出しの例:

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

その後、ジェネリック型のコンストラクターは<!> quot; params <!> quot;を必要としません。少し、混乱はありません。

他のヒント

おそらく、Paramsの代わりにIEnumerableを渡すことができます

public Houses(IEnumerable<T> InitialiseElements){}

2番目のコンストラクターは、より正確な 一致です。これは、どのコンストラクターが正しいかを評価するために使用される基準です。

オリジナルにはクラスに関する情報が多すぎなかったため、次のようにします。

コンパイラーは、新しいHouse(1,2)が2番目のコンストラクターと完全に一致することを決定し、それを使用します。

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
        }
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top