2009-07-30 16 views
6

Ho il seguente metodo:Come ottenere il compilatore C# per inferire tipi generici?

public TResult Get<TGenericType, TResult>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

In questo momento, un utente di questo metodo deve usare in questo modo:

//Notice the duplicate int type specification 
int number = Get<SomeGenericType<int>, int>(); 

Perché devo specificare TResult nel metodo defintion? Il compilatore conosce già TResult da quando l'ho specificato in TGenericType. Idealmente (se il compilatore C# è stato un po 'più intelligente), il mio metodo sarà simile a questa:

public TResult Get<TGenericType>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

Così l'utente può semplicemente usare in questo modo:

//Much cleaner 
int number = Get<SomeGenericType<int>>(); 

C'è un modo per farlo cosa voglio fare?

+0

Penso che rimuovere alcuni qualificatori come * stupido * dalla descrizione della domanda aiuterà. – EFraim

+0

È il compilatore che è stupido, giusto? ;) Ho rimosso il commento estraneo. Questa è in realtà una domanda ragionevole senza di essa. –

+0

Dato che hai risposto che non è possibile utilizzare solo alcuni dei parametri dei tipi, forse dovresti riformulare la tua domanda in termini di ciò che vorresti ottenere. Così com'è, la tua domanda è "come faccio a compilare il codice compilatore C# che viola la definizione del linguaggio C#?" Come tale, dovrebbe essere chiuso come "non una vera domanda". –

risposta

8

La specifica C# non consente inferire metà degli argomenti di tipo. Dovresti lasciare che il compilatore deduca tutti gli argomenti di tipo (che non sono sempre applicabili, come nel tuo caso) o specificarli manualmente.

UPDATE (Rispondi al commento): Mentre io non sono nella squadra di C# per dare una risposta assoluta alla tua domanda, la mia ipotesi è che la complessità della risoluzione di sovraccarico (che è già strabiliante, tu lo sai che se leggessi quella sezione di specifiche C#) aumenterebbe significativamente se volessero consentire che metà dei tipi fosse dedotta e metà non (specialmente considerando il fatto che puoi sovraccaricare i metodi solo dal numero di argomenti generici).

+0

Ma perché lo hanno specificato nella specifica C#? Non è come se ci fosse qualcosa di pericoloso a riguardo. –

+0

Esaminare alcune delle regole C++, inclusa la specializzazione parziale dei modelli e il funzionamento degli specificatori di accesso. Di solito le cose funzionano senza problemi, ma ci sono trucchi in agguato qua e là. Dato che una delle idee alla base di Java e C# era quella di evitare la complicazione di C++, accettando invece un piccolo inconveniente, questo è giusto in linea. –

1

Dipende ...

Se stai usando solo SomeGenericType<TResult>, si può fare:

public TResult Get<TResult>() where TResult : IConvertible { 
    SomeGenericType<TResult> myInstance = ... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

non v'è necessariamente un modo per mettere il primo tipo in là, in questo caso . Poiché il tuo esempio non sta passando esplicitamente come parametro a SomeGenericType<TResult>, suggerisce che ciò sarebbe possibile.

Altrimenti, è necessario specificare completamente tutti gli argomenti generici. Sfortunatamente, è proprio così come è in C#.

+0

Certo, ma ho bisogno di utilizzare SomeGenericType nel metodo. Aggiornerò il mio codice di esempio per renderlo chiaro. –

+0

Sì, ma guarda il mio codice - finché non viene passato come parametro al metodo, puoi usare SomeGenericType nel metodo (es .: se ne costruisci uno nel metodo). Dato che conosci TResult, questo funziona bene. Come ho detto, può funzionare in alcuni casi ... –

+0

Scusa, volevo dire che ho bisogno di usare TGenericType (vedi il mio codice di esempio aggiornato). –