是否可以重载基于另一种方法的方法?
Is it possible to overload a method based on another method?
问题标题可能不是很清楚,但这是我想做的:
说,我有一个静态classA
。此 class 包含一个名为 B
的静态函数。它有 10 多个重载。尽管有这么多重载,该功能还是非常基本的;与class的其他成员无关。我知道我可以通过导入正确的命名空间并使用:
从任何地方访问它
string bar = A.B("foo", true, 5) // Then do whatever with bar
现在,假设我有另一个 class 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
方法,我需要做什么?我必须手动编写所有单独的重载还是有更好的方法?
Will I have to write all the separate overloads manually
如果您希望每个 B
的重载都有 D
的重载,那么是的,您必须完全这样做。
这是静态方法缺点的一个很好的例子。
如果可以,将这些静态方法转换为实例方法(也许是一些新工人class,用静态工厂方法return实例,或者使用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[]
,但 there doesn't seem to be an easy way to do that.
为什么不让您的基本方法成为具有泛型类型的扩展方法,然后在单个扩展方法中简单地实现任何类型特定的逻辑?
问题标题可能不是很清楚,但这是我想做的:
说,我有一个静态classA
。此 class 包含一个名为 B
的静态函数。它有 10 多个重载。尽管有这么多重载,该功能还是非常基本的;与class的其他成员无关。我知道我可以通过导入正确的命名空间并使用:
string bar = A.B("foo", true, 5) // Then do whatever with bar
现在,假设我有另一个 class 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
方法,我需要做什么?我必须手动编写所有单独的重载还是有更好的方法?
Will I have to write all the separate overloads manually
如果您希望每个 B
的重载都有 D
的重载,那么是的,您必须完全这样做。
这是静态方法缺点的一个很好的例子。
如果可以,将这些静态方法转换为实例方法(也许是一些新工人class,用静态工厂方法return实例,或者使用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[]
,但 there doesn't seem to be an easy way to do that.
为什么不让您的基本方法成为具有泛型类型的扩展方法,然后在单个扩展方法中简单地实现任何类型特定的逻辑?