Eric Lippert ha spiegato nel suo post sul blog al http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx perché i vincoli non sono considerati per l'inferenza di tipo, il che ha senso dato che i metodi non possono essere sovraccaricati semplicemente cambiando i vincoli di tipo. Tuttavia, mi piacerebbe trovare un modo per creare un'istanza di un oggetto utilizzando due tipi generici, uno che può essere dedotto e un altro che può essere dedotto se sono stati considerati i vincoli, senza dover specificare nessuno dei tipi.C'è una soluzione alternativa a C# che non è in grado di dedurre argomenti di tipo generico usando i vincoli di tipo?
Dati i tipi:
public interface I<T>
{
Other<T> CreateOther();
}
public class C : I<string>
{
public Other<string> CreateOther()
{
return new Other<string>();
}
}
public class Other<T>
{
}
e la fabbrica:
public static class Factory1
{
public static Tuple<T, Other<T1>> Create<T, T1>(T o) where T : I<T1>
{
return new Tuple<T, Other<T1>>(o, o.CreateOther());
}
}
il seguente codice desiderato non viene compilato:
messaggiopublic void WontCompile()
{
C c = new C();
var v = Factory1.Create(c); // won't compile
}
L'errore è "CS0411 Errore: il digitare argomenti per il metodo 'yo.Factory1.Create (T)' non può essere dedotto dall'utilizzo. Prova a specificare il tipo a rguments esplicitamente. ", che è in linea con ciò che Eric ha detto nel suo post sul blog.
Così, si può semplicemente specificare gli argomenti di tipo generico in modo esplicito, come il messaggio di errore suggerisce:
public void SpecifyAllTypes()
{
C c = new C();
var v = Factory1.Create<C, string>(c); // type is Tuple<C, Other<string>>
}
Se non vogliamo specificare argomenti di tipo e non abbiamo bisogno di mantenere il tipo C, siamo in grado di utilizzare il seguente fabbrica:
public static class Factory2
{
public static Tuple<I<T1>, Other<T1>> CreateUntyped<T1>(I<T1> o)
{
return new Tuple<I<T1>, Other<T1>>(o, o.CreateOther());
}
}
e ora specificare:
public void Untyped()
{
C c = new C();
var v = Factory2.CreateUntyped(c); // type is Tuple<I<string>, Other<string>>
}
Ho Comunque, desidero mantenere il tipo C nell'oggetto restituito e non specificare i tipi.