c#泛型类型的重载错误

时间:2012-12-09 14:10:10

标签: c# generics overloading

我想使用方法重载来根据不同的泛型类型获得不同的结果。这是行不通的。我的代码清楚地表明了

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)?

3 个答案:

答案 0 :(得分:4)

这不起作用。

重载在编译时完全解决;泛型类型参数在运行时解析 由于编译器不知道Tint,因此您的代码将始终调用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

当然,通过一些额外的工艺(以及泛型类型的使用),您可以在许多不同情况下广泛地重复使用该代码段。

还有一句话:在这个例子中,我使用了直接类型比较来表示你的具体例子。请注意,在处理继承的类型时,这将无法正常工作(当然,还有一些其他含糊之处:)。