【问题标题】:Why my TryInvokeMember is not called?为什么我的 TryInvokeMember 没有被调用?
【发布时间】:2012-07-08 17:31:45
【问题描述】:

我的 DynamicObject 实现如下所示:

public class DynCallsite: DynamicObject
{
    public DynCallsite(ScriptPlayer player)
    {
        _player = player;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        var ftt = new CallTranslator();

        var request = ftt.CreateXmlRequest(binder.Name, args);

        var callResult = _player.CallFunction(request);
        result = ftt.DeserializeXmlRequest(callResult);

        return true;            
    }

    private ScriptPlayer _player;
}

这就是我使用这个对象的实例的方式:

class DynHost
{
    public DynHost()
    {
        _callSite = new DynCallsite(new ScriptPlayer());
    }    

    public dynamic Callsite
    {
        get { return _callsite; }   // A breakpoint put here will be hit
    }
}

// *snip*

var dh = new DynHost();
dh.Callsite.MyMethod("str1", 5, "str2");

曾经工作:),我不确定发生了什么变化。调试器没有中断 TryInvokeMember 调用,我收到了RuntimeBinderException。此类在与正在运行的程序集不同的程序集中定义(以正常方式引用它,通过从同一解决方案添加对项目的引用)。

对实例执行调用后,我得到以下堆栈跟踪:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError(Microsoft.CSharp.RuntimeBinder.Errors.CError pError) + 0x23 字节
Microsoft.CSharp.RuntimeBinder.Semantics.LangCompiler.SubmitError(Microsoft.CSharp.RuntimeBinder.Errors.CParameterizedError 错误)+ 0x24 字节
Microsoft.CSharp.RuntimeBinder.Errors.ErrorHandling.ErrorTreeArgs(Microsoft.CSharp.RuntimeBinder.Errors.ErrorCode id, Microsoft.CSharp.RuntimeBinder.Errors.ErrArg[] prgarg) + 0x53 字节 Microsoft.CSharp.RuntimeBinder.Semantics.MemberLookup.ReportErrors() + 0x6cd 字节
Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCall(Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder 有效负载,Microsoft.CSharp.RuntimeBinder.Semantics.EXPR 调用对象, Microsoft.CSharp.RuntimeBinder.RuntimeBinder.ArgumentObject[] 论据, System.Collections.Generic.Dictionary 字典) + 0x206 字节 Microsoft.CSharp.RuntimeBinder.RuntimeBinder.DispatchPayload(System.Dynamic.DynamicMetaObjectBinder 有效负载,Microsoft.CSharp.RuntimeBinder.RuntimeBinder.ArgumentObject[] 论据, System.Collections.Generic.Dictionary 字典)+ 0xb1 字节
Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(System.Dynamic.DynamicMetaObjectBinder 有效载荷, System.Collections.Generic.IEnumerable 参数,System.Dynamic.DynamicMetaObject[] 参数,输出 System.Dynamic.DynamicMetaObject deferredBinding) + 0xbc 字节
Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(System.Dynamic.DynamicMetaObjectBinder 有效载荷, System.Collections.Generic.IEnumerable 参数,System.Dynamic.DynamicMetaObject[] 参数,输出 System.Dynamic.DynamicMetaObject deferredBinding) + 0x56 字节
Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(System.Dynamic.DynamicMetaObjectBinder 动作,Microsoft.CSharp.RuntimeBinder.RuntimeBinder 活页夹, System.Collections.Generic.IEnumerable 参数, System.Collections.Generic.IEnumerable arginfos,System.Dynamic.DynamicMetaObject onBindingError) + 0x2ca 字节 Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder.FallbackInvokeMember(System.Dynamic.DynamicMetaObject 目标,System.Dynamic.DynamicMetaObject[] 参数, System.Dynamic.DynamicMetaObject 错误建议)+ 0x77 字节
System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember.AnonymousMethod__10(System.Dynamic.DynamicMetaObject e) + 0x1b 字节
System.Dynamic.DynamicObject.MetaDynamic.BindInvokeMember(System.Dynamic.InvokeMemberBinder 活页夹,System.Dynamic.DynamicMetaObject[] args) + 0xb8 字节 System.Dynamic.InvokeMemberBinder.Bind(System.Dynamic.DynamicMetaObject 目标,System.Dynamic.DynamicMetaObject[] args) + 0x36 字节 System.Dynamic.DynamicMetaObjectBinder.Bind(object[] args, System.Collections.ObjectModel.ReadOnlyCollection 参数,System.Linq.Expressions.LabelTarget returnLabel) + 0xea 字节 System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> 站点,对象 [] args) + 0x80 字节 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite 站点,对象 arg0,十进制 arg1,双 arg2) + 0x30e 字节 MyApp.DynCallsite.MyMethod(string str1, decimal number, string str2) Line 96 + 0x17d bytes C#

看起来好像我使用的是 DynamicObject 实例而不是我的专用派生类。但是,我确认不是这种情况,因为我可以在调试器中检查调用站点对象,它显示的是 DynCallsite。这是什么原因造成的?

【问题讨论】:

  • 你还没有展示你是如何使用这个对象的。如果你能制作一个简短但完整的程序来演示这个问题,那真的很有帮助。
  • 为防止将来出现I'm not sure what changed 时刻,请考虑使用版本控制系统,例如mercurial
  • 谢谢,我现在状态很好(快乐的 git 用户已经快 2 年了),但这是一个旧项目,我不是 :)
  • 嘿,我想知道您是否还应该覆盖 TryGetMember 它返回 true 或 false,告诉 DLR 天气该成员存在于实例中。
  • 我确实实现了 TryGetMember 和 TrySetMember,但我认为它们是针对属性类型的东西(并且它们是相应地实现的)。由于脚本对象将接受不存在的属性,它们总是返回 true(并获取/设置播放器的动态属性)。并且其中的断点也没有被命中。

标签: c# dynamic dynamicobject


【解决方案1】:

我想如果你直接使用动态它会起作用。问题可能是您通过属性返回它。这种方式适用于 WPF 数据绑定。如果我直接将动态作为 DataContext 提供,则绑定有效。如果我像你一样使用属性,我会得到绑定错误。

【讨论】:

    猜你喜欢
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2022-10-15
    • 2011-04-11
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多