[英]Accessing a dynamic's property threw an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'
I am passing a handler function as an argument to another function.我将处理程序函数作为参数传递给另一个函数。 One of the arguments of the handler is a dynamic object and I am accessing one of its properties.
处理程序的参数之一是动态对象,我正在访问其属性之一。
Here is an example:下面是一个例子:
protected virtual void OnTime(dynamic timed, HttpResponseMessage response, TimeSpan time)
{
_logger.Write(timed?.name);
}
And here is how the handler gets invoked:以下是调用处理程序的方式:
OnTime?.Invoke(new {name = dto.name, dto, request }, httpResponseMessage, elapsed);
This worked well.这工作得很好。 Then I shuffled some things around and it broke.
然后我洗了一些东西,它坏了。 The dynamic object comes in as expected with all of its properties but now
timed?.name
throws Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
exception complaining that the object does not have a definition of property name
.动态对象按预期进入它的所有属性,但现在
timed?.name
抛出Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
异常,抱怨该对象没有属性name
的定义。
I looked at these answers for a solution:我查看了这些答案以寻求解决方案:
Why does the assignment from a dynamic object throw a RuntimeBinderException? 为什么动态对象的赋值会抛出 RuntimeBinderException?
Dynamic throwing Microsoft.CSharp.RuntimeBinder.RuntimeBinderException on private types 在私有类型上动态抛出 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
and the following works:和以下作品:
Dictionary<string, object> values = ((object)timed)
.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(v));
( Get properties of a Dynamic Type ) ( 获取动态类型的属性)
but I am not sure why direct access stopped working.但我不确定为什么直接访问停止工作。 Any ideas?
有任何想法吗? Thank you!
谢谢!
I discovered the reason it broke.我发现了它破裂的原因。 Initially, both the handler and the function the handler is passed in belonged to the same assembly.
最初,处理程序和处理程序传入的函数都属于同一个程序集。 After the refactoring the handler and the object invoking it were split into different projects and namespaces thus preventing the binding at compile time.
重构处理程序后,调用它的对象被拆分为不同的项目和命名空间,从而防止在编译时进行绑定。
The solution was to no longer pass a dynamic but a serialized object:解决方案是不再传递动态而是序列化对象:
OnTime?.Invoke(JsonConvert.SerializeObject(new { name = dto.Name, dto, request }), httpResponseMessage, elapsed);
and then consume it as:然后将其消耗为:
protected virtual void OnTime(string timed, HttpResponseMessage response, TimeSpan time)
{
var operation = JsonConvert.DeserializeAnonymousType(timed, new { name = string.Empty });
_logger.Write(operation.name);
}
Decoupling thus requires the extra step of serialization but allows for more reuse of the code.因此,解耦需要额外的序列化步骤,但允许更多地重用代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.