是否可以基于另一个方法重载一个方法

本文关键字:方法 一个 重载 是否 另一个 | 更新日期: 2023-09-27 18:20:41

问题标题可能不太清楚,但我想做的是:

比方说,我有一个静态类A。这个类包含一个名为B的静态函数。它有10多个过载。尽管有这么多过载,但这个功能基本上是可以实现的;这与班上的其他成员无关。我知道我可以通过导入正确的名称空间并使用从任何地方访问它

string bar = A.B("foo", true, 5) // Then do whatever with bar

现在,假设我有另一个类C(不在A中)。现在我想在C中制作一个名为D的方法,它在各个方面都与A.B相同。我试过:

public static class C {
    public static string D(string p1, bool p2, int p3) {
        return A.B(p1, p2, p3);
    }
}

但是要像A.B一样重载这个D方法,我该怎么办?我必须手动编写所有单独的重载吗?或者有更好的方法吗?

是否可以基于另一个方法重载一个方法

我必须手动写入所有单独的过载吗

如果您希望每个B的过载都有一个D的过载,那么是的,您必须做到这一点。

为什么不让您的基本方法成为具有泛型类型的扩展方法,然后在单个扩展方法中简单地实现任何类型特定的逻辑?

这是静态方法缺点的一个很好的例子。

如果可以的话,可以将这些静态方法转换为实例方法(可能是一些新的辅助类,使用静态工厂方法返回实例,或者使用IOC)。这样,您就可以更灵活地使用继承来避免重复代码。

更新

经过一些反馈,我有了一个想法,可能的。使用反射来获得B的所有版本的参数列表,并与D.的参数列表进行比较

public static int D(params object[] paramArray)
{
    var paramTypes = paramArray.Select(x => x.GetType());
    var method = typeof(Static.A).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
        .Where(m => m.Name == "B" && m.GetParameters().Select(x => x.ParameterType).SequenceEqual(paramTypes))
        .FirstOrDefault();
    if (method != null)
    {
        return (int)method.Invoke(null, paramArray);
    }
    throw new Exception("Overloaded method not found");
}

这种方法的缺点是没有参数的编译时检查,没有Intellisense等。如果不重复A.B()的每个版本的规范,我想不出一种绕过这一问题的方法,比如:

    private static int GenericD(object[] paramArray, MethodBase caller)
    {
        var paramTypes = caller.GetParameters().Select(x => x.ParameterType);
        var method = typeof(Static.A).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
            .Where(m => m.Name == "B" && m.GetParameters().Select(x => x.ParameterType).SequenceEqual(paramTypes))
            .FirstOrDefault();
        if (method != null)
        {
            return (int)method.Invoke(null, paramArray);
        }
        throw new Exception("Overloaded method not found");
    }
    public static int D(string p)
    {
        object[] paramArray = new object[] { p };
        return GenericD(paramArray, MethodInfo.GetCurrentMethod());
    }
    public static int D(string p, int x)
    {
        object[] paramArray = new object[] { p, x };
        return GenericD(paramArray, MethodInfo.GetCurrentMethod());
    }

在这个解决方案中,D()的每个版本几乎相同,但并不完全相同。理想情况下,您可能希望以某种方式以编程方式将方法的参数列表转换为object[],但似乎没有简单的方法。