【问题标题】:Generate method if not existent如果不存在则生成方法
【发布时间】:2014-06-23 11:46:34
【问题描述】:

上下文

我有一个 C# 类 PyroProxycall(string method, params object[] arguments) 方法

public class PyroProxy : IDisposable {

    public object call(string method, params object[] arguments)
}

这是远程对象的代理类。

动机

一直使用 call 方法在代码中看起来不太好。

问题

假设 PyroProxy 类没有方法test_method()。 如何使以下代码工作?

PyroProxy p = new PyroProxy();
p.test_method();

test_method 的代码看起来像

public object test_method(params object[] arguments) {
    return call("test_method", arguments); // you get the point
}

这可能是我没有找到的重复项,也许在编译时或运行时有可能。我能做些什么来接近这个目标?提示表示赞赏。有关于如何注入方法的答案。我找到了ExpandoObject,但它没有告诉我如何创建未知方法。

【问题讨论】:

  • 你想在运行时添加这些方法吗?
  • 您提供的链接不是真正描述了您必须做什么吗? dictionary.Add("Shout", new Action(() => { Console.WriteLine("Hellooo!!!"); })); person.Shout();
  • @private_meta 这意味着你必须在调用它之前设置它。 dcastro 的回答不需要那个。
  • @DavidG 我希望这些方法在运行时出现。我不在乎它们何时添加。
  • 您是否考虑过使用DynamicProxy?像Dynamic 这样的问题是为了获得神奇的行为,你实际上必须在动态的同时调用它们。如果您声明要覆盖的所有成员 virtual 则可以创建一个代理类,它只需调用 call 方法并返回结果。试试 castle DynamicProxy,因为它在这个目的上相当不错。它有点慢,但是当您代理远程调用时,它会产生零差异。

标签: c# dynamic methods proxy


【解决方案1】:

您应该从DynamicObject 派生,然后覆盖TryInvokeMember 方法。

public class PyroProxy : DynamicObject
{
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        Console.WriteLine(binder.Name + " was invoked");
        result = call(binder.Name, args);
        return true;
    }
}

dynamic proxy = new PyroProxy();
proxy.SomeMethod(); //prints "SomeMethod was invoked"

【讨论】:

  • 我选择了这个解决方案,虽然没有实现,因为它捕捉了代理所使用语言的动态特性。如果需要,它还允许将getWidth() 转换为get_width(),以保持语言风格不受破坏。 Here 是我们会使用它的项目。
  • 您的提案已进入code of Pyrolite。非常感谢!
【解决方案2】:

为什么不使用extension methods

public static class ExtensionMethods
{
    public static object test_method(this PyroProxy proxy, params object[] arguments)
    {
        return proxy.call("test_method", arguments); // you get the point
    }
}

【讨论】:

  • 我更喜欢它而不是“自动代理生成”,它可以让您跟踪您的应用程序实际使用了哪些方法,并防止拼写错误破坏您的一天。
  • 我可以做类似public static class ExtensionMethods : DynamicObject 的事情吗?我只是好奇。
  • 不,扩展方法只是假装该方法属于this关键字之后的类。包含它的类必须是静态的,因此我认为在您的场景中不可用。
  • @C.Evenhuis 同意。除非我错过了问题中的某些内容,否则这个答案对我来说比使用dynamic 的答案要好得多。代码中没有任何拼写错误,唯一硬编码的地方方法名称是在单个静态类中。
  • @User:对您的问题和建议的解决方案有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2012-05-04
  • 2016-05-29
  • 2013-01-10
  • 2013-10-24
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多