【问题标题】:Generic overloaded method with nullable param call concrete type具有可为空参数的通用重载方法调用具体类型
【发布时间】:2012-02-07 03:51:17
【问题描述】:

我希望能够调用具有 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));
    }
}

【问题讨论】:

  • 您希望double? 去哪里?
  • 尝试在调用 Foo() 时显式转换参数

标签: c# .net generics overloading nullable


【解决方案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 的调用,将转到这个新的重载。

【讨论】:

  • 谢谢 Anthony,dynamic 做了我想做的事。由于我提供的示例不是我的真实代码,因此可以传递的类型数量有限。我喜欢您将所有方法更改为一种通用方法的想法。我要看看我的重载是否可以支持它。非泛型方法是遗留代码,所以我想限制引入的新代码数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
相关资源
最近更新 更多