2011-10-04 15 views
6

Ho la seguente funzione in C#:Sintassi zucchero per doppio generica funzione di

bool Handle<TCommandHandler, TModel>(TModel model) where TCommandHandler : ICommandHandler<TModel> { 
    // ... 
    _container.Resolve<TCommandHandler>(); 
    // ... 
} 

Dal TModel risulta da un parametro di funzione che voglio un modo per non specifica il tipo quando si chiama una funzione. Idealmente voglio chiamarlo come:

Handle<MyCommandHandler>(model); 

Dal momento che questo è probabilmente impossibile, mi si avvicinò con il seguente:

HandleTemp<TModel> Handle<TModel>(TModel model) { 
    return new HandleTemp<TModel>(model); 
} 

public class HandleTemp<TModel> { 
    private TModel _model; 
    public HandleTemp(TModel model) { _model = model;} 

    public bool With<TCommandHandler>() where TCommandHandler : ICommandHandler<TModel> { 
    } 
} 

Così ora sto chiamando le cose come:

Handle(model).With<MyCommandHandler>(); 

Ci sono altre possibilità? Ho fatto qualcosa di completamente sbagliato con la mia soluzione?

+0

Se il metodo fosse statico, allora questo si sarebbe potuto fare meglio in una ' classe'. – nawfal

risposta

4

No, l'analisi e la soluzione sembrano corrette. In effetti, l'inferenza di tipo generico può funzionare solo su base tutto-o-niente. Se ci sono alcuni parametri generici che non possono essere dedotti, tutti devono essere esplicitamente indicati. Personalmente mi piacerebbe un modo per dire "ti preoccupi di questi parametri, ti dirò questo", ma ... quello non esiste.

L'unica altra opzione è quella di aggiungere un ulteriore artificiale regolare parametro per permettergli di inferire il parametro generico - un po 'schifo.

Un'altra opzione: sfidare l'ipotesi che i generici siano necessari qui. Ad esempio, potrebbe essere solo un'istanza Type? Would:

bool Handle<TModel>(TModel model, Type type)... 
... 
Handle(model, typeof(MyCommandHandler)); 

lavoro, ad esempio? Non posso rispondere direttamente, poiché non conosco i dettagli del tuo metodo _container.Resolve<TCommandHandler>();, per sapere se è possibile regolare per prendere uno Type anziché uno <T>.

+1

Sì, che potrebbe essere facilmente convertito in argomento di "Tipo", ma mi piacerebbe avere un controllo in fase di compilazione (che i tipi generici offrono) per rendere impossibile il passaggio in un "Tipo" che non implementa my ICommandHandler . Grazie per aver esaminato la mia implementazione :) – Shaddix

+0

Vedi anche la risposta di Eric Lippert a una domanda su [Mumble Typing] (http://stackoverflow.com/questions/5693503/what-is-mumble-typing/5693505#5693505). – Brian

1

Tutto il fabbisogno del compilatore C# è una dimostrazione del tipo negli argomenti, quindi anziché tentare di inserirlo negli argomenti generici (nel sito di utilizzo) creare qualcosa che permetta di fornire un argomento che aiuti il ​​compilatore a identificarlo genere. Per rendere meno confusione, ecco un esempio:

// Your classes/interfaces. 
class Container 
{ 
    public static T Resolve<T>() 
    { 
     Console.WriteLine("Resolving {0}", typeof(T).FullName); 
     return default(T); 
    } 
} 
interface ICommandHandler<TModel> 
{ 
    void DoSomething(); 
} 

// An implemented ICommandHandler. 
public class WackyCommandHandler : ICommandHandler<string> 
{ 
    public void DoSomething() { } 
} 

// Used to help the C# compiler identify types. 
public static class Identify 
{ 
    public static TypeIdentity<TType> TheType<TType>() 
    { 
     return null; // You don't actually need an instance. 
    } 
} 
public sealed class TypeIdentity<TType> 
{ 
    private TypeIdentity() { } 
} 

// Your method 
static bool Handle<TCommandHandler, TModel>(TModel model, TypeIdentity<TCommandHandler> handler) 
    where TCommandHandler : ICommandHandler<TModel> 
{ 
    var item = Container.Resolve<TCommandHandler>(); 
    return true; 
} 

// And the usage site: 
var a = "hello"; 
Handle(a, Identify.TheType<WackyCommandHandler>()); 
Console.ReadLine(); 
+1

grazie, ho capito, ma mi sembra che la mia implementazione sarà più chiara per me quando la userò :) – Shaddix

Problemi correlati