假设我们有一个带有单一泛型方法的接口:
public interface IExtender
{
T GetValue<T>(string tag);
}
和一个简单的实现A,它根据“tag”参数返回两种不同类型(B和C)的实例:
public class A : IExtender
{
public T GetValue<T>(string tag)
{
if (typeof(T) == typeof(B) && tag == null)
return (T)(object) new B();
if (typeof(T) == typeof(C) && tag == "foo")
return (T)(object) new C();
return default(T);
}
}
可以避免双重演员(T)(object)
吗?或者,有没有办法告诉编译器“嘿,我确信这个演员阵容不会在运行时失败,只是让我在没有首先投射到对象的情况下执行它!”
答案 0 :(得分:5)
或者,有没有办法告诉编译器“嘿,我确信这个演员阵容不会在运行时失败,只是让我在没有首先投射到对象的情况下进行演绎!”
不,该语言是故意设计的,以防止这种情况发生。 Eric Lippert blogged about this recently。我同意这很烦人,但它确实有一定道理。
老实说,像这样的“通用”方法通常有点像设计气味。如果方法必须针对各种不同类型具有特殊情况,则至少应考虑使用单独的方法。 (GetB
,GetC
)
答案 1 :(得分:4)
检查此样本:
public T GetValue<T>(string tag) where T : class, new()
{
if (typeof(T) == typeof(B) && tag == null)
return new T();
if (typeof(T) == typeof(C) && tag == "foo")
return new T();
return default(T);
}
不需要强制转换,你可以创建“T”的实例,只需添加说T是一个类的通用约束,它有无参数构造函数,所以你不需要创建另一个基类型,你可以确定只有合适的类型才能通过这种通用方法。
答案 2 :(得分:3)
public T MyMethod<T>(string tag) where T : class
{
return new A() as T;
}
答案 3 :(得分:0)
不,那是不可能的。唯一的方法是让编译器了解T
的其他假设。正如the list of generic parameter constraints所证明的那样,C#中没有定义约束来要求特定强制转换的可用性。
答案 4 :(得分:0)
如果您让B和C实现相同的界面,则可以使用T
上的type constraint。可能不完全是你想要的,但正如其他人所建议的那样,你真正不可能。
public interface IclassBndC {}
public class B : IclassBandC {}
public class C : IclassBandC {}
public class A : IExtender
{
public T GetValue<T>(string tag) where T : IclassBandC
{
if (tag == null)
return new B();
if (tag == "foo")
return new C();
return default(T);
}
}
答案 5 :(得分:0)
您可以使用dynamic来存储实际结果,但是必须确保泛型参数类型是您返回的正确类型。
TResult GetResult<TResult>()
{
dynamic r = 10;
return r;
}