我有以下代码,我试图从泛型函数内部达到正确的重载函数:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
class A
{
public void a(int a) { Console.WriteLine("a: int"); }
public void a(string a) { Console.WriteLine("a: string"); }
public void a(int a, int b) { Console.WriteLine("a: int int"); }
public void a(string a, string b) { Console.WriteLine("a: string string"); }
public void a(params object[] args) { Console.WriteLine("a: object"); }
}
class B
{
A a;
public B(A _a) { this.a = _a; }
public void b1<T>(T t) { a.a(t); }
public void b2<T1, T2>(T1 t1, T2 t2) { a.a(t1, t2); }
public void b(int i) { Console.WriteLine("b: int "); b1(i); }
public void b(string i) { Console.WriteLine("b: string"); b1(i); }
public void b(int i, int b) { Console.WriteLine("b : int int"); b2(i,b);}
public void b(string i, string b) { Console.WriteLine("b: string string"); b2(i,b); }
}
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
Console.WriteLine("Hello, world!");
B b = new B(new A());
b.b(1);
b.b("1");
b.b(1,2);
b.b("1", "2");
}
}
}
输出:
Hello, world!
b: int
a: object
b: string
a: object
b : int int
a: object
b: string string
a: object
预期产出:
Hello, world!
b: int
a: int
b: string
a: string
b : int int
a: int int
b: string string
a: string string
如果参数不匹配,则应调用public void a(params object[] args)
。
对于实际使用,A
为EventSource,a
为WriteEvent
。
B
是一个代码库,包含许多(~1000)b
个带有复杂参数的命令。
我可以更改b1
和b2
.. bn
(n~10),以便轻松完成工作。
a
的参数只是int, string, long
或Guid
等原生类型。
我能做些什么来实现它? 我愿意接触任何其他好方法来实现解决方案。
答案 0 :(得分:1)
基本上,来自泛型方法的调用的重载解析仍然在编译时发生,因此除非存在泛型类型约束,否则对于函数内部的大多数事物,泛型类型被认为是object
。
如果您想要不同的行为,则需要运行时重载解析。实现它的一种方法是使用dynamic
类型进行应该使用一些重载的方法调用:
public void b1<T>(T t) { a.a((dynamic)t); }
public void b2<T1, T2>(T1 t1, T2 t2) { a.a((dynamic)t1, (dynamic)t2); }
但是,这基本上会忽略泛型类型:
假设你写了
public void b(int i) { Console.WriteLine("b: int "); b1<object>(i); }
然后动态会忽略您明确给出的object
类型,仍会调用int
的{{1}}重载
另一种方法是反射,检查泛型类型并尝试调用匹配方法重载。