Domanda

Ho una classe generica in C # con 2 costruttori:

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

La costruzione di un oggetto usando int come tipo generico e passando due int come argomenti fa sì che il costruttore 'errato' venga chiamato (dal mio punto di vista).

es. Houses<int> houses = new Houses<int>(1,2) - chiama il secondo costruttore. Passare qualsiasi altro numero di ints nel costruttore chiamerà il 1o costruttore.

Esiste un modo per aggirare questo se non rimuovere la parola chiave params e costringere gli utenti a passare un array di T quando usano il primo costruttore?

È stato utile?

Soluzione

Una soluzione più chiara sarebbe quella di avere due metodi statici di fabbrica. Se li metti in una classe non generica, puoi anche beneficiare dell'inferenza di tipo:

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

Esempio di chiamata:

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

Quindi il costruttore del tuo tipo generico non ha bisogno del " params " un po 'e non ci sarà confusione.

Altri suggerimenti

Forse invece di Params potresti passare in IEnumerable

public Houses(IEnumerable<T> InitialiseElements){}

Il secondo costruttore è una corrispondenza più esatta , che è i criteri utilizzati per valutare quale costruttore è corretto.

Dato quanto segue poiché l'originale non aveva troppe informazioni sulla classe ecc.

Il compilatore deciderà esattamente che la nuova House (1,2) corrisponde esattamente al secondo costruttore e lo utilizzerà, nota che ho preso la risposta con il maggior numero di voti e non ha funzionato.

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
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top