Questa è una domanda un po 'lunga, quindi per favore abbiate pazienza con me.Un elenco <> di Func <> s, errore di compilazione con tipo di ritorno generico, ma perché?
Devo creare una mappatura tra un insieme di stringhe e le corrispondenti chiamate di metodo generiche per ogni stringa. Comunque ho incontrato un problema di compilazione, spiegato in basso.
Nel mio scenario sto usando un Dictionary<>
, ma il problema esiste allo stesso modo per un List<>
. Per semplicità sto usando un List<>
nell'esempio qui sotto.
Considerare questi tre classi:
public abstract class MyBase { /* body omitted */ }
public class MyDerived1 : MyBase { /* body omitted */ }
public class MyDerived2 : MyBase { /* body omitted */ }
e un metodo in qualche altra classe:
public class Test
{
public T GetT<T>() where T : MyBase { /* body omitted */ }
}
In un'altra classe, posso dichiarare una List<Func<MyBase>>
come questo:
public class SomeClass
{
public void SomeFunc()
{
var test = new Test();
var list1 = new List<Func<MyBase>>
{
test.GetT<MyDerived1>,
test.GetT<MyDerived2>
};
}
}
Questo va tutto bene e bene.
Ma, cosa succede se voglio avere una funzione che restituisce un classe generica come questa:
public class RetVal<T> where T : MyBase { /* body omitted */ }
public class Test
{
public RetVal<T> GetRetValT<T>() where T : MyBase
{
return null;
}
}
E voglio creare un equivalente List<>
di utilizzare questa funzione. cioè una lista >>?
public class Class1
{
public void SomeFunc()
{
var test = new Test();
var list2 = new List<Func<RetVal<MyBase>>>
{
test.GetRetValT<MyDerived1>, // compile error
test.GetRetValT<MyDerived2> // compile error
};
}
}
Ottengo errori di compilazione di Expected a method with 'RetVal<MyBase> GetRetValT()' signature
.
Quindi, c'è un modo per aggirare questo, o c'è un approccio alternativo che posso usare per creare la mia stringa ... metodo generico chiamate mappature?
E 'una questione di varianza. Fondamentalmente, un 'RetVal' * non è * a 'RetVal '. Maggiori dettagli quando ho tempo. –
Ciò che @JonSkeet ha detto è vero. È una legge in C#. Se vuoi inserire 'RetVal' MyDerived a 'RetVal ' MyBase ', devi fare in modo che il' RetVal' accetti un generico non tipizzato, ad esempio 'RetVal '. Vedere un esempio qui: http://www.ienablemuch.com/2012/05/generics-object-orientation-untyped.html –
Posso essere del tutto fuori base su questo, ma non vorrei l'idea di restituire un generico violare l'idea che il generico debba (eventualmente) risolversi in qualcosa che il compilatore conosce al momento della compilazione? Cioè, la ragione per cui il compilatore lancia questo errore è che si aspetta che tu fornisca il metodo che può restituire un tipo specifico (che mi rendo conto è opposto a quello che stai cercando di fare). Solo un'osservazione, come ho detto, può essere molto lontana qui ... –