从通用函数内部调用正确的重载

时间:2017-07-12 11:30:26

标签: c# generics overloading

我有以下代码,我试图从泛型函数内部达到正确的重载函数:

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)

对于实际使用,AEventSourceaWriteEventB是一个代码库,包含许多(~1000)b个带有复杂参数的命令。 我可以更改b1b2 .. bn(n~10),以便轻松完成工作。

a的参数只是int, string, longGuid等原生类型。

我能做些什么来实现它? 我愿意接触任何其他好方法来实现解决方案。

1 个答案:

答案 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}}重载

另一种方法是反射,检查泛型类型并尝试调用匹配方法重载。

相关问题