处理未在动态对象上定义的C#方法(又名respond_to / method_missing)

时间:2009-07-10 16:05:21

标签: dynamic c#-4.0

鉴于C#4中的新动态支持,是否可以以这样的方式编写类:如果在实例上调用方法并且该方法不存在,则将dispatch传递给另一个方法?这可能类似于:

public class Apple : ... {
  // ...

  private ... MethodMissing(string name, ...) {
    if (name == "TurnIntoOrange") {
      // do something
    }
  }
}

dynamic d = new Apple();
d.TurnIntoOrange();       // Not actually defined on Apple; will pass to MethodMissing.

在元编程的更一般标题下,其他语言会称之为“method_missing支持”。我不确定C#特意称之为什么。但这可能吗?

1 个答案:

答案 0 :(得分:17)

绝对。要么实现IDynamicMetaObjectProvider,要么从DynamicObject派生出更简单的路线。有关一些好的示例,请参阅DLR documentation

以下是DynamicObject的简短示例:

using System;
using System.Dynamic;

public class MyDynamic : DynamicObject
{
    public override bool TryInvokeMember
        (InvokeMemberBinder binder,
         object[] args,
         out object result)
    {
        Console.WriteLine("I would have invoked: {0}",
                          binder.Name);
        result = "dummy";
        return true;
    }

    public string NormalMethod()
    {
        Console.WriteLine("In NormalMethod");
        return "normal";
    }
}

class Test
{
    static void Main()
    {
        dynamic d = new MyDynamic();
        Console.WriteLine(d.HelloWorld());
        Console.WriteLine(d.NormalMethod());
    }
}

<强> <plug>

我在2nd edition of C# in Depth中有一个更大的DynamicObject示例,但我还没有实现IDyamicMetaObjectProvider。我会在本书发布之前这样做,但早期的访问版本目前只有DynamicObject示例。顺便说一句,如果你今天购买它的价格是半价 - 使用代码 twtr0711 。我稍后会编辑这个答案以删除该位:)

<强> </plug>