C#:泛型方法不';t调用特定的方法重载
我试图在C#中创建一个泛型方法,它将根据其主体中的参数数据类型调用不同的方法,然后处理它们的结果。我试图通过创建一个通用包装器方法来实现这一点,然后提供处理方法的几个重载—包括一个在没有特定重载可用时将使用的通用重载 当我直接调用处理方法时,正确选择了适当的版本。然而,当我从包装器方法调用它时,它总是选择泛型方法,即使我传递给它的特定数据类型有匹配的重载 有没有办法调整代码,使其按我需要的方式运行?或者我必须使用不同的方法 我需要的代码与Mono 2.6兼容C#:泛型方法不';t调用特定的方法重载,c#,generics,mono,unity3d,polymorphism,C#,Generics,Mono,Unity3d,Polymorphism,我试图在C#中创建一个泛型方法,它将根据其主体中的参数数据类型调用不同的方法,然后处理它们的结果。我试图通过创建一个通用包装器方法来实现这一点,然后提供处理方法的几个重载—包括一个在没有特定重载可用时将使用的通用重载 当我直接调用处理方法时,正确选择了适当的版本。然而,当我从包装器方法调用它时,它总是选择泛型方法,即使我传递给它的特定数据类型有匹配的重载 有没有办法调整代码,使其按我需要的方式运行?或者我必须使用不同的方法 我需要的代码与Mono 2.6兼容 using System; cla
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();
}
}
使用系统;
班级计划
{
静态无效函数(T val)
{
Console.WriteLine(“通用函数”);
}
静态无效函数(int-val)
{
Console.WriteLine(“Int Func”);
}
静态无效函数(字符串值)
{
Console.WriteLine(“字符串函数”);
}
静态void FuncWrap(T val)
{
控制台。写(“包装:”);
Func(val);
}
静态void Main(字符串[]参数)
{
Func(2);
Func(“马铃薯”);
Func(2.0);
二,;
土豆卷;
FuncWrap(2.0);
Console.Read();
}
}
有没有办法纠正这种行为
根据C语言规范,这已经是正确的行为。在FuncWrap
中调用的Func
重载通常在编译时确定,因此它不能根据执行时间类型选择不同的Func
重载
但是,改变行为的一种方法是使用动态类型:
static void FuncWrap<T>(T val)
{
Console.Write("Wrap: ");
dynamic x = val;
Func(x);
}
不过,这显然相当可怕。对不起,我说得不对。我的意思是“正确的”,就是让它按照我需要的方式运行。这一动态似乎不适用于Mono 2.6(我使用的是Unity引擎中的代码)。是的,第二种方法是不可取的,我正在寻找更干净(最好更快)的方法。@TomFrooxiusMariank:看看Mono 2.6的发行说明,它应该得到支持——可能Unity实际上是在限制使用旧的配置文件。(它需要.NET4配置文件。)如果没有
动态
,您可能最好在我的答案末尾进行黑客攻击。。。这将相当好地执行(比dynamic更好,后者基本上使用反射)。当然,你可以自己使用反射,但这不会很快。如果没有一个是合适的,那么你应该考虑重新设计。我看,我现在可能不太符合当前统一版Unity了,我会检查我是否可以改变配置文件,但我不确定这是否不会有一些不希望的后果。如果它不起作用,我可能会重新编写代码以避免需要此功能。谢谢你的帮助。@TomFrooxiusMariank如果你不能使用dunamic,也不想做很多假设,你可以使用我为其他问题准备的课程:。它允许您使用fluent api确定案例。你可以修改我的答案。我正在准备图书馆,所以你们可以等它,若它符合你们的要求的话。示例:obj.StronglyInvoke().When(Func).When(Func.Invoke()代码>您可以使用同时接受int和string的FuncWrap重载(或者直接使用Func方法而不使用wrapp)。
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);
}
}