gpt4 book ai didi

c# - 方法工厂——案例与反射(reflection)

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

前几天我遇到了一些代码,我想知道这是否是最好的方法。我们有一个方法,它从一些 Web 表单数据中获取一个字符串,并根据传入的字符串对一个对象执行某些操作。目前,它使用反射来确定要采取的操作,但我想知道 switch 语句是否会更好.

例子:

编辑:如 Lucerno 所述,我为代表添加了第三个选项

public class ObjectManipulator
{
private void DoX(object o) { }
private void DoY(object o) { }
private void DoZ(object o) { }

public void DoAction(string action, object o)
{
switch (action)
{
case "DoX":
DoX(o);
break;
case "DoY":
DoY(o);
break;
case "DoZ":
DoZ(o);
break;
default:
throw new Exception(string.Format(
"Cannot locate action:{0}", action));
}
}

public void DoActionViaReflection(string action, object o)
{
MethodInfo method = typeof(ObjectManipulator).
GetMethod(action, new Type[] { typeof(object) });
if (method == null)
{
throw new Exception(string.Format(
"Cannot locate action:{0}", action));
}
else
{
method.Invoke(this, new object[] { o });
}
}
private Dictionary<string, Action<object>> _methods;
public ObjectManipulator()
{
_methods = new Dictionary<string, Action<object>>()
{
{"DoX", o => DoX(o)},
{"DoY", o => DoY(o)},
{"DoZ", o => DoZ(o)}
};
}
public void DoActionViaDelegates(string action, object o)
{
if (!_methods.ContainsKey(action))
{
throw new Exception(string.Format(
"Cannot locate action:{0}", action));
}
else
{
_methods[action](o);
}
}

}

第一个示例使用了开关,如您所见,它可能会变得非常冗长。第二个要短得多,但使用反射,我知道有些人像躲避瘟疫一样避免反射。

一种方法的性能会明显好于另一种吗?

如果有 100 个不同的操作而不是只有 3 个,性能会改变吗?

如果您正在阅读代码,您更愿意在代码中看到哪个?

最佳答案

第一种情况几乎总是更快。然而,它的性能来自于它可以在编译时提前绑定(bind)的事实,但这也是它最大的缺点:例如,这种方法不能处理动态加载的程序集,而且更容易出错,因为它是命令式而不是声明式。 (例如,忘记新执行的操作是一件可能很快发生的事情。)

我通常的方法是在发现时使用反射来实现此类模式,但在调用时使用委托(delegate)。这使您可以灵活地使用反射方法,其性能非常接近早期绑定(bind)方法。

  • 发现阶段:使用反射来查找成员(使用属性、接口(interface)、签名和/或编码约定)。在您的情况下,您始终具有相同的签名,因此要使用的委托(delegate)将是 Action<object> .将这些成员添加到 Dictionary<string, Action<object>>例如,从 MethodInfo 创建一个委托(delegate)使用 CreateDelegate() .

  • 调用阶段:通过键获取委托(delegate)并调用它,这很简单(这里假设字典名为methods):methods[action](o)

关于c# - 方法工厂——案例与反射(reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4234421/

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