尝试在动态创建的程序集上绑定动态方法会导致RuntimeBinderException

时间:2013-04-17 16:02:06

标签: c# .net dynamic reflection dynamic-language-runtime

我有一个方便的实用程序方法,它接受代码并吐出内存中的程序集。 (它使用CSharpCodeProvider,虽然我不认为这应该重要。)这个程序集与其他任何反射一样工作,但是当与dynamic关键字一起使用时,它似乎失败了{{1 }}:

  

'object'不包含'Sound'的定义

示例:

RuntimeBinderException

有谁知道DLR无法解决这个问题的原因?有什么办法可以解决这个问题吗?

编辑:

createAssembly方法:

免责声明:其中一些内容包含扩展方法,自定义类型等。但它应该是不言自明的。

var assembly = createAssembly("class Dog { public string Sound() { return \"woof\"; } }");
var type = assembly.GetType("Dog");
Object dog = Activator.CreateInstance(type);

var method = type.GetMethod("Sound");
var test1Result = method.Invoke(dog, null); //This returns "woof", as you'd expect

dynamic dog2 = dog;
String test2Result = dog2.Sound(); //This throws a RuntimeBinderException

2 个答案:

答案 0 :(得分:5)

上课public

var assembly = createAssembly("public class Dog { public string Sound() ...
                               ^

解决了我机器上的问题。

答案 1 :(得分:0)

这可能是一种解决方法。

//instead of this
//dynamic dog2 = dog;    

//try this
dynamic dog2 = DynWrapper(dog);    
String test2Result = dog2.Sound();//Now this works.

public class DynWrapper : DynamicObject {
        private readonly object _target;


        public DynWrapper(object target) {
            _target = target;                
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {   
            //for the sake of simplicity I'm not taking arguments into account,
            //of course you should in a real app.
            var mi = _target.GetType().GetMethod(binder.Name);
            if (mi != null) {
                result = mi.Invoke(_target, null);                                        
                return true;
            }
            return base.TryInvokeMember(binder, args, out result);
        }
    }

PS:我尝试将此作为评论发布(因为这是一种解决方法而不是答案)但是不能这样做,因为它很长......