Domanda

In template C ++, si può specificare che un certo tipo di parametro è un valore predefinito. Cioè se non esplicitamente specificato, verrà utilizzato il tipo T.

Può questo essere fatto o approssimata in C #?

Sto cercando qualcosa di simile:

public class MyTemplate<T1, T2=string> {}

In modo che un'istanza del tipo che non specifica esplicitamente T2:

MyTemplate<int> t = new MyTemplate<int>();

Sarebbe essenzialmente:

MyTemplate<int, string> t = new MyTemplate<int, string>();

In definitiva sto guardando un caso in cui v'è un modello che è abbastanza ampiamente utilizzato, ma sto considerando l'espansione con un parametro di tipo aggiuntivo. Potrei sottoclasse immagino, ma ero curioso di sapere se c'erano altre opzioni in questa vena.

È stato utile?

Soluzione

Subclassing è l'opzione migliore.

Vorrei sottoclasse la classe generica principale:

class BaseGeneric<T,U>

con una classe specifica

class MyGeneric<T> : BaseGeneric<T, string>

In questo modo è facile mantenere la logica in un unico luogo (la classe base), ma anche facile da fornire entrambe le opzioni di utilizzo. A seconda della classe, c'è probabilmente molto poco lavoro aggiuntivo necessario per rendere questo accada.

Altri suggerimenti

Una soluzione è la creazione di sottoclassi. Un altro userei invece, è metodi di fabbrica (in combinazione con var parola chiave).

public class MyTemplate<T1,T2>
{
     public MyTemplate(..args..) { ... } // constructor
}

public static class MyTemplate{

     public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
     {
         return new MyTemplate<T1, T2>(... params ...);
     }

     public static MyTemplate<T1, string> Create<T1>(...args...)
     {
         return new MyTemplate<T1, string>(... params ...);
     }
}

var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();

Nell'esempio precedente val2 è di tipo MyTemplate<int,string> e non un tipo derivato da esso.

Un tipo class MyStringTemplate<T>:MyTemplate<T,string> non è dello stesso tipo di MyTemplate<T,string>. Questo potrebbe comportare alcuni problemi in alcuni scenari. Per esempio non è possibile lanciare un'istanza di MyTemplate<T,string> a MyStringTemplate<T>.

è anche possibile creare un sovraccarico di classe in questo modo

public class MyTemplate<T1, T2> {
    public T1 Prop1 { get; set; }
    public T2 Prop2 { get; set; }
}

public class MyTemplate<T1> : MyTemplate<T1, string>{}

C # non supporta tale caratteristica.

Come hai detto, è possibile creare una sottoclasse (se non è sigillato, e duplicare tutte le dichiarazioni del costruttore), ma è una cosa completamente diversa.

Purtroppo C # non supporta ciò che si sta cercando di fare. Sarebbe una caratteristica difficile da attuare, dato che il tipo predefinito per un parametro dovrebbe rispettare i vincoli generici e molto probabilmente creare mal di testa quando il CLR ha cercato di garantire la tipo di sicurezza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top