Ho il sospetto che la risposta è no, ma voglio sapere se è possibile fare qualcosa di simile:È possibile vincolare un parametro del tipo di metodo generico C# come "assegnabile dal parametro di tipo della classe contenente"?
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TSomeInterface>()
// This doesn't compile.
where TSomeClass : TSomeInterface
{
//...
}
}
Quello che voglio dire per indicare nell'esempio di cui sopra (non funzionante) è quello di limitare TSomeInterface
tale che può essere qualsiasi classe base, interfaccia implementata o conversione implicita (se si vuole veramente ottenere) di MyGenericClass
.
NOTA: ho il sospetto che la ragione per cui questo non è mai stato implementato in C# è che i vincoli generici non sono davvero vuole essere contratti di codice, che è come sto cercando di usare qui. Non mi interessa davvero quale sia il tipo TSomeInterface
, purché sia implementato da TSomeClass
.
Finora, ho hacked questo insieme:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TIntermediateType, TSomeInterface>()
where TIntermediateType : TSomeClass, TSomeInterface
{
//...
}
}
Questo più o meno fa rispettare il vincolo che voglio (che TSomeClass
deve ereditare da, o, nel caso di un'interfaccia, implementare, TSomeInterface
), ma chiamando è molto goffo, perché devo specificare TIntermediateType
(anche se voglio davvero di valutare contro TSomeClass
):
var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod(TSomeClass, TSomeInterface);
Inoltre, l'hack di cui sopra è rotto perché il chiamante potrebbe in oy specifica una sottoclasse di TSomeClass
come primo parametro di tipo, dove solo la sottoclasse implementa TSomeInterface
.
Il motivo che voglio fare questo è che sto scrivendo un modello di fabbrica fluente per un servizio WCF e vorrei come per evitare che il chiamante (al momento della compilazione) dal tentativo di creare un endpoint con un contratto che la classe di servizio non implementa. Posso ovviamente controllarlo a runtime (WCF in effetti fa questo per me), ma sono un grande fan del controllo in fase di compilazione.
Esiste un modo migliore/più elegante per ottenere ciò che sono dopo?
Questo è praticamente impossibile dal momento che stai cercando di mescolare i generici con il runtime. – Polity
No, non lo sono. Sto solo cercando di applicare un vincolo generico che (per quanto posso dire) il linguaggio C# non consente (vincolando un parametro di tipo tale che sia una superclasse o l'interfaccia implementata di un parametro di tipo nella classe contenitore). –
Per quanto vedo, si tenta di vincolare la classe generica in base ai dati di tipo che si alimentano con un metodo.Se si desidera limitare la classe generica, è necessario farlo a livello di classe (logicamente) altrimenti non è possibile per il compilatore JIT creare una classe concreta. – Polity