2014-09-05 17 views
9

Sto cercando di creare un metodo generico in C#, che chiamerà diversi metodi basati sul tipo di argomento argomento nel suo corpo ed elaborerà i risultati successivamente. Sto cercando di ottenere questo risultato creando un metodo generico di wrapper e quindi fornendo diversi overload del metodo di elaborazione, incluso uno generico che verrà utilizzato se non è disponibile un sovraccarico specifico.C#: il metodo generico non chiama il metodo specifico overload

Quando chiamo direttamente il metodo di elaborazione, la versione appropriata è selezionata correttamente. Tuttavia, quando lo chiamo dal metodo wrapper, seleziona sempre quello generico, anche se c'è un sovraccarico corrispondente per il tipo di dati specifico che gli ho passato.

C'è un modo per regolare il codice per farlo funzionare nel modo in cui è necessario? O devo usare un approccio diverso.

Ho bisogno che il codice sia compatibile con Mono 2.6.

using System; 

class Program 
{ 
    static void Func<T>(T val) 
    { 
     Console.WriteLine("Generic Func"); 
    } 

    static void Func(int val) 
    { 
     Console.WriteLine("Int Func"); 
    } 

    static void Func(string val) 
    { 
     Console.WriteLine("String Func"); 
    } 

    static void FuncWrap<T>(T val) 
    { 
     Console.Write("Wrap: "); 
     Func(val); 
    } 

    static void Main(string[] args) 
    { 
     Func(2); 
     Func("Potato"); 
     Func(2.0); 

     FuncWrap(2); 
     FuncWrap("Potato"); 
     FuncWrap(2.0); 

     Console.Read(); 
    } 
} 
+0

si potrebbero avere overload di FuncWrap che accettano anche int e string (o semplicemente usano i metodi Func direttamente senza wrapping). –

risposta

13

Esiste un modo corretto questo comportamento?

È già il comportamento corretto in base alle specifiche del linguaggio C#. Il sovraccarico di Func chiamato in FuncWrap è normalmente determinato in fase di compilazione, quindi non è possibile selezionare un diverso sovraccarico Func in base al tipo di esecuzione.

Un modo per cambiare il comportamento, tuttavia, è quello di utilizzare la tipizzazione dinamica:

static void FuncWrap<T>(T val) 
{ 
    Console.Write("Wrap: "); 
    dynamic x = val; 
    Func(x); 
} 

che saranno ora eseguire la risoluzione di sovraccarico in fase di esecuzione in base al reale tipo del valore di x. Ciò comporta un costo in termini di prestazioni, ma dovrebbe fare ciò che si desidera.

In alternativa, si potrebbe codificare la conoscenza dei sovraccarichi:

static void FuncWrap<T>(T val) 
{ 
    Console.Write("Wrap: "); 
    if (typeof(T) == typeof(string)) 
    { 
     Func((string)(object)val); 
    } 
    else if (typeof(T) == typeof(int)) 
    { 
     Func((int)(object)val); 
    } 
    else 
    { 
     Func(val); 
    } 
} 

Questo è chiaramente abbastanza orribile però.

+0

Siamo spiacenti, non l'ho scritto correttamente. Intendevo "corretto" come nel farlo comportarsi nel modo in cui ho bisogno. La dinamica non sembra funzionare con Mono 2.6 (sto usando il codice nel motore Unity). Sì, il secondo metodo non è desiderabile, sto cercando qualcosa di più pulito (e idealmente più veloce). –

+0

@TomFrooxiusMariank: Osservando le note di rilascio per Mono 2.6, dovrebbe * essere * supportato - potrebbe essere che Unity stia effettivamente limitando le cose ad un profilo più vecchio. (Avrebbe bisogno del profilo .NET 4.) Senza 'dynamic', probabilmente staresti meglio con l'hack alla fine della mia risposta ... che funzionerà ragionevolmente bene (meglio della dinamica, che fondamentalmente sta usando riflessione). Potresti usare la riflessione, naturalmente, ma non sarà veloce. Se nessuno di questi è adatto, probabilmente dovresti considerare una riprogettazione. –

+0

Vedo, probabilmente sono sfortunato con l'attuale versione Unity di Unity ora, controllerò se posso cambiare il profilo in qualche modo, ma non sono sicuro che ciò non avrà conseguenze indesiderate. Se non funziona, probabilmente rileggerò il codice per evitare la necessità di questa funzione. Grazie per il vostro aiuto. –

Problemi correlati