具有可为空的参数调用具体类型的泛型重载方法 [英] Generic overloaded method with nullable param call concrete type
问题描述
我希望能够调用具有Nullable参数的通用foo方法.当Foo方法的主体调用Foo()时,它将进行递归操作,从而导致堆栈溢出(没有.com).有没有一种方法可以让if语句中的调用以运行时类型调用正确的重载?
I want to be able to call the generic foo method which has a Nullable param. When the body of the Foo method calls the Foo(), it goes recursive, resulting in a stack overflow (without the .com). Is there a way to have the call in the if statement call the correct overload with the runtime type?
我知道可以更改名称,并且我知道为什么会进行递归,但是不知道另一种写法.
I know changing the names would do it and I understand why the recursion is happening, but don't know of another way to write this.
感谢您的光临.
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));
}
}
推荐答案
泛型是一种编译时功能,在程序运行之前就已经确定了重载解决方案.如您所言,如果要强制执行运行时决策,则可以采用 dynamic
来实现该目标(在C#4+中).除此之外,您只需将其强制转换为int和bool之间的适用类型即可.
Generics are a compile time feature, overload resolution has been decided before the program ever runs. If you want to, as you say, force a runtime decision, you could employ dynamic
to achieve that goal (in C# 4+). Short of that, you simply must cast to the applicable type between int and bool otherwise.
if (arg.HasValue)
Foo((dynamic)arg.Value, defaultValue);
但是要当心!这只能解决 int
和 bool
的问题.可以将其他类型传递给泛型方法,并且这些类型将在后续调用中继续解析为泛型方法.
But beware! This only solves your problem for int
and bool
. Other types could be passed to the generic method, and those will continue to resolve to the generic method on the subsequent call.
Foo(5.0, 10.0); // would still overflow with your given methods
根据您的初步判断,如果您想支持 int
, string
和 bool
,只需重载即可.如果要支持任何给定的T,请为T创建一个重载.
Follow your initial judgment, if you want to support int
, string
, and bool
, simply have those overloads. If you want to support any given T, create an overload for T.
static void Foo<T>(T arg, T defaultValue)
{
Console.WriteLine(string.Format("I'm a T arg={0}, default={1}", arg, defaultValue));
}
如果适用,重载分辨率仍会选择 int
, bool
, string
或 T?
重载基于编译时间信息.其他所有调用,以及带有 arg.Value
的 调用,都会进入这个新的重载状态.
Overload resolution will still pick int
, bool
, string
, or T?
overloads if they are applicable based upon compile time information. All other calls, and the call with arg.Value
, will go to this new overload.
这篇关于具有可为空的参数调用具体类型的泛型重载方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!