Perché devo fornire tipi di parametri esplicitamente generici Mentre il compilatore deve inferire il tipo?

Perché devo fornire tipi di parametri esplicitamente generici Mentre il compilatore deve inferire il tipo?

public static T2 Cast(this T1 arg) where T2 : class where T1 : class { return arg as T2; } 

Esempio di utilizzo:

  objOfTypeT2 = objOfTypeT1.Cast(); 

Rispetto al mio utilizzo desiderato con un compilatore più intelligente:

  objOfTypeT2 = objOfTypeT1.Cast(); 

o forse dovrei essere più intelligente 🙂

Attenzione che fornisco il tipo di reso . Non voglio fornire l’object su cui ho chiamato la funzione, il metodo è un metodo di estensione .

La specifica limita l’inferenza dei parametri di tipo per metodi generici a tutto o niente. Non puoi avere un’inferenza parziale.

La logica sta probabilmente semplificando le regole di inferenza di tipo (che sono già piuttosto complesse, dato che devono prendere in considerazione anche le regole di sovraccarico).

L’inferenza non considera il tipo di ritorno; puoi, tuttavia, provare a dividere i generici; ad esempio, puoi scrivere codice per consentire:

 .Cast().To() 

avendo (non testato, solo indicativo)

 public static CastHelper Cast(this T obj) { return new CastHelper(obj); } public struct CastHelper { private readonly TFrom obj; public CastHelper(TFrom obj) { this.obj = obj;} public TTo To() { // your code here } } 

Ho usato la soluzione di Marc Gravell e mi piace, ma posso presentare un’altra alternativa.

Poiché i parametri generici vengono desunti dai parametri, un’altra opzione consiste nell’utilizzare un parametro out per il risultato anziché un valore restituito.

Questo è stato ansible per molto tempo, ma il C # di oggi ti permette di dichiarare la variabile inline, che trovo essere un stream utilizzabile.

 public static void Cast(this T1 arg, out T2 result) where T2 : class where T1 : class { result = arg as T2; } 

Puoi chiamare questo come segue

 objOfTypeT1.Cast(out Type2 objOfTypeT2);