gpt4 book ai didi

C# - 将所有方法参数传递给另一个方法?

转载 作者:太空狗 更新时间:2023-10-29 23:24:33 27 4
gpt4 key购买 nike

我有一个类,它有三个重载方法。比方说,有:

class MyChildClass
{
public void myMethod(int i)
{ /* do something with i */ }
public void myMethod(int a, string b)
{ /* get i from a and b and call: */ myMethod(i); }
public void myMethod(string c, string d)
{ /* get i from c and d and call: */ myMethod(i); }
}

现在我希望这个类成为其他(父)类中的私有(private)字段,但我需要这三个方法可以访问。现在,我只是做了:

class MyBaseClass
{
private MyChildClass myObject = new myChildClass(); // or similar
public void myMethod(int i)
{ myObject.myMethod(i); }
public void myMethod(int a, string b)
{ myObject.myMethod(a, b); }
public void myMethod(string c, string s)
{ myObject.myMethod(c, d); }
}

有没有一种方法可以将其实现为一个简短的方法?看起来像的东西:

public void myMethod(unknownListOfArgumentsOfDifferentTypes args)
{ myObject.myMethod(args); }

我尝试使用 public void myMethod(params object[] something) 但它没有用。有可能吗,还是我必须将每种方法“转换”到另一种方法中?

编辑: 子类有各种方法和字段,我希望只有父类可以访问这些方法和字段。这就是为什么我不希望 parent 在它之后派生。我没有解释,对不起,如果它看起来像子类只包含这三个方法。这些是我希望作为父类的公共(public)方法访问的方法。

最佳答案

你为什么不这样做

class MyChildClass : MyBaseClass
{
}

同样的效果,更少的代码,这样MyChildClass就是一个MyBaseClass


如果您使用反射实现某种通用外观,您只会降低性能,绕过类型安全的好处并延迟问题的发现。

你也会有一个“有一个”关系而不是“是一个”与你的类名不一致的关系。


如果您想放弃这种简单性及其相关好处,您可以使用 GetMethodBySig这篇文章接受了扩展。

像这样,

class SemiGenericFacade<T> where T : new()
{
private readonly t = new T();

public void CallVoidOnT(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))

var match = typeof(T).GetMethodBySig(typeof(void), paramTypes)
.Single(mi => mi.Name == name);

match.Invoke(this.t, parameters);
}
}

根据 Piotr Justyna 的评论,实现和使用此方法会导致猫变成老虎并吃掉她的小猫。


如果您要这样做,添加到链接的扩展中是有意义的

public static class Extensions
{
public static MethodInfo GetMethodByNameThenSig(
this Type type,
string name,
Type returnType,
params Type[] parameterTypes)
{
return type.GetMethods().Where((m) =>
{
if (m.Name != name)
{
return false;
}

if (m.ReturnType != returnType)
{
return false;
}

var parameters = m.GetParameters();
if ((parameterTypes == null || parameterTypes.Length == 0))
{
return parameters.Length == 0;
}

if (parameters.Length != parameterTypes.Length)
{
return false;
}

for (int i = 0; i < parameterTypes.Length; i++)
{
if (parameters[i].ParameterType != parameterTypes[i])
{
return false;
}
}

return true;
}).Single();
}
}

你可以这样使用,

class GenericFacade<T> where T : new()
{
private readonly t = new T();

public void CallOnInternal(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))

var match = typeof(T).GetMethodByNameThenSig(
name,
typeof(void),
paramTypes);

match.Invoke(this.t, parameters);
}

public TResult CallOnInternal<TResult>(string name, params object[] parameters)
{
var paramTypes = parameters.Select(p => typeof(p))

var match = typeof(T).GetMethodByNameThenSig(
name,
typeof(TResult),
paramTypes);

return (TResult)match.Invoke(this.t, parameters);
}
}

最终编辑

查看涉及使用反射的代码并考虑与类型安全性损失相关的成本。我建议最好以传统方式明确建立“has-a”关系。

关于C# - 将所有方法参数传递给另一个方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13838288/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com