C#:通用方法不会调用特定的方法重载
我想在C#中创建一个通用方法,它将调用基于它的正文中的参数数据类型的不同方法,然后处理它们的结果。我试图通过创建一个通用的包装方法来实现这一点,然后提供处理方法的几个重载 - 包括一个通用的方法,如果没有特定的超载可用的话。C#:通用方法不会调用特定的方法重载
当我直接调用处理方法时,正确选择了适当的版本。但是,当我从包装器方法调用它时,它总是选择通用的,即使对于传递给它的特定数据类型存在匹配的重载。
是否有任何方法来调整代码,使其行为我需要的方式?或者我必须使用不同的方法。
我需要代码与Mono 2.6兼容。
using System;
class Program
{
static void Func<T>(T val)
{
Console.WriteLine("Generic Func");
}
static void Func(int val)
{
Console.WriteLine("Int Func");
}
static void Func(string val)
{
Console.WriteLine("String Func");
}
static void FuncWrap<T>(T val)
{
Console.Write("Wrap: ");
Func(val);
}
static void Main(string[] args)
{
Func(2);
Func("Potato");
Func(2.0);
FuncWrap(2);
FuncWrap("Potato");
FuncWrap(2.0);
Console.Read();
}
}
有什么办法解决此问题?
根据C#语言规范,它已经是正确的行为。在FuncWrap
内调用的Func
的过载通常在编译时间确定为,所以它不能根据执行时间类型选择不同的Func
过载。改变行为的
的一种方式,但是,使用动态类型:
static void FuncWrap<T>(T val)
{
Console.Write("Wrap: ");
dynamic x = val;
Func(x);
}
基础上,实际类型的x
值在执行时也将立即执行重载解析。这招致了性能成本,但应该做你想做的事情。
或者,你可以在重载的硬编码知识:
static void FuncWrap<T>(T val)
{
Console.Write("Wrap: ");
if (typeof(T) == typeof(string))
{
Func((string)(object)val);
}
else if (typeof(T) == typeof(int))
{
Func((int)(object)val);
}
else
{
Func(val);
}
}
这显然很可怕,但。
对不起,我没有正确地说出来。我的意思是“正确的”,因为它会按照我需要的方式行事。 动态似乎不适用于Mono 2.6(我在Unity引擎中使用代码)。 是的,第二种方法是不可取的,我正在寻找更干净的东西(并且理想的更快)。 – 2014-09-05 12:10:33
@TomFrooxiusMariank:查看Mono 2.6的发行说明,应*支持*它可能是Unity实际上限制了一些旧的配置文件。 (它需要.NET 4配置文件。)如果没有'dynamic',你可能会在我的答案结束时使用黑客最好的解决方案......这样做表现会相当好(比动态更好,这基本上是使用反射)。你当然可以使用反射,但这不会很快。如果这些都不合适,你应该考虑重新设计。 – 2014-09-05 12:13:49
我明白了,我现在可能不太会用目前的Unity版本的Unity,但我会检查是否可以以某种方式更改配置文件,但我不确定这是否会导致不希望的后果。 如果它不起作用,我可能会重新编写代码以避免使用此功能。 感谢您的帮助。 – 2014-09-05 12:17:46
你可以有一个接受int和string的FuncWrap重载(或者直接使用Func方法直接不包装)。 – 2014-09-05 12:20:57