具有可空参数的通用重载方法调用具体类型

时间:2012-02-07 03:51:18

标签: c# .net generics overloading nullable

我希望能够调用具有Nullable参数的泛型foo方法。当Foo方法的主体调用Foo()时,它会递归,导致堆栈溢出(没有.com)。有没有办法让if语句中的调用使用运行时类型调用正确的重载?

我知道更改名称会这样做,我理解为什么递归正在发生,但不知道另一种写这个的方法。

感谢您的光临。

class Program {
    static void Main(string[] args) {
        int? x = 5;
        int y = 10;
        Foo(x, y);
    }

    static void Foo<T>(Nullable<T> arg, T defaultValue) where T : struct {
        if (arg.HasValue)
            Foo(arg.Value, defaultValue);
    }

    static void Foo(int arg, int defaultValue) {
        Console.WriteLine(string.Format("I'm an int arg={0}, default={1]}", arg, defaultValue));
    }

    static void Foo(string arg, int defaultValue) {
        Console.WriteLine(string.Format("I'm an string arg={0}, default={1]}", arg, defaultValue));
    }

    static void Foo(bool arg, int defaultValue) {
        Console.WriteLine(string.Format("I'm an double arg={0}, default={1]}", arg, defaultValue));
    }
}

1 个答案:

答案 0 :(得分:1)

泛型是一个编译时功能,在程序运行之前已经决定了重载决策。如果您想要强制执行运行时决策,您可以使用dynamic来实现该目标(在C#4 +中)。除此之外,你只需要在int和bool之间转换为适用的类型。

  if (arg.HasValue) 
        Foo((dynamic)arg.Value, defaultValue); 

但要注意!这仅解决了intbool的问题。其他类型可以传递给泛型方法,并且这些类型将继续解析为后续调用中的泛型方法。

 Foo(5.0, 10.0); // would still overflow with your given methods

按照您的初步判断,如果您想支持intstringbool,只需拥有这些重载。如果要支持任何给定的T,请为T创建重载。

static void Foo<T>(T arg, T defaultValue)
{
    Console.WriteLine(string.Format("I'm a T arg={0}, default={1}", arg, defaultValue));
}

如果根据编译时信息适用,则重载决策仍然会选择intboolstringT?重载。所有其他电话,arg.Value的通话都将转到此新的重载。