Eric Lippert在他的博客文章http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx中解释了为什么类型约束不被考虑在类型推断中,这是有道理的,因为方法不能通过简单地改变类型约束来进行重载。然而,我想找到一种使用两个泛型类型实例化对象的方法,其中一个可以被推断,另一个如果考虑约束就可以被推断,而无需指定任何类型。
给定以下类型:
以下期望的代码将无法编译:
错误信息是“error CS0411:无法从使用中推断方法'yo.Factory1.Create(T)'的类型参数。尝试显式指定类型参数。”,这与Eric在他的博客文章中说的一致。
因此,我们可以简单地按照错误信息建议显式指定泛型类型参数:
如果我们不想指定类型参数并且不需要保留类型C,我们可以使用以下工厂:
然而,我希望在返回的对象中保留类型C,而不指定类型。
给定以下类型:
public interface I<T>
{
Other<T> CreateOther();
}
public class C : I<string>
{
public Other<string> CreateOther()
{
return new Other<string>();
}
}
public class Other<T>
{
}
和工厂:
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());
}
}
以下期望的代码将无法编译:
public void WontCompile()
{
C c = new C();
var v = Factory1.Create(c); // won't compile
}
错误信息是“error CS0411:无法从使用中推断方法'yo.Factory1.Create(T)'的类型参数。尝试显式指定类型参数。”,这与Eric在他的博客文章中说的一致。
因此,我们可以简单地按照错误信息建议显式指定泛型类型参数:
public void SpecifyAllTypes()
{
C c = new C();
var v = Factory1.Create<C, string>(c); // type is Tuple<C, Other<string>>
}
如果我们不想指定类型参数并且不需要保留类型C,我们可以使用以下工厂:
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());
}
}
现在指定:
public void Untyped()
{
C c = new C();
var v = Factory2.CreateUntyped(c); // type is Tuple<I<string>, Other<string>>
}
然而,我希望在返回的对象中保留类型C,而不指定类型。