我想使用方法重载来根据不同的泛型类型获得不同的结果。这是行不通的。我的代码清楚地表明了
static class Helper
{
public static bool Can(int i)
{
return true;
}
public static bool Can(Object o)
{
return false;
}
}
class My<T>
{
public static bool can = Helper.Can(default(T));
}
Console.WriteLine(Helper.Can(default(int)));//True,it is OK
Console.WriteLine(My<int>.can);//false?? why the overload doesn't work
Console.WriteLine(My<Object>.can);//false
为什么My<int>
调用Helper.Can(Object o)而不是Helper.Can(int i)?
答案 0 :(得分:4)
这不起作用。
重载在编译时完全解决;泛型类型参数在运行时解析
由于编译器不知道T
是int
,因此您的代码将始终调用Can(Object)
。
答案 1 :(得分:3)
通常,它会在编译时解析为Object,但您可以使用 dynamic 关键字告诉它等到运行时:
class My<T>
{
public static bool can = CanWithDynamic();
private static bool CanWithDynamic() {
dynamic runtimeT = default(T);
return Helper.Can(runtimeT);
}
因此,这将适用于您正在尝试执行的操作,并且将调用正确的重载。但是,与在运行时解析的任何内容一样,存在与之相关的性能成本。可能不是很多,但如果你经常调用这种方法,它可能会产生影响。
答案 2 :(得分:1)
它有点冗长,但你可以通过使用Reflection实现你想要的东西:
class My<T>
{
static bool doStuff()
{
var rightMehod = typeof(Helper).GetMethods().Where(p =>
{
if (!p.Name.Equals("Can"))
return false;
if (!p.ReturnType.Equals(typeof(bool)))
return false;
if (p.GetParameters().Length != 1)
return false;
var par = p.GetParameters().First();
return par.ParameterType.Equals(typeof(T));
}).FirstOrDefault();
if (rightMehod == null)
{
return Helper.Can(default(T));
}
else
{
return (bool)rightMehod.Invoke(null, new object[] { default(T) });
}
}
public static bool can = doStuff();
}
这样,
My<string>.can == false
My<int>.can == true
My<object>.can == false
当然,通过一些额外的工艺(以及泛型类型的使用),您可以在许多不同情况下广泛地重复使用该代码段。
还有一句话:在这个例子中,我使用了直接类型比较来表示你的具体例子。请注意,在处理继承的类型时,这将无法正常工作(当然,还有一些其他含糊之处:)。