我将一个处理程序函数作为参数传递给另一个函数。处理程序的一个参数是动态对象,我正在访问它的一个属性。
下面是一个示例:
protected virtual void OnTime(dynamic timed, HttpResponseMessage response, TimeSpan time)
{
_logger.Write(timed?.name);
}
下面是如何调用处理程序:
OnTime?.Invoke(new {name = dto.name, dto, request }, httpResponseMessage, elapsed);
这个效果很好。然后我把一些东西弄乱了,它坏了。动态对象与其所有属性一样出现,但现在timed?.name
抛出Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
异常,抱怨对象没有属性name
的定义。
我看了这些答案,找出了一个解决办法:
Why does the assignment from a dynamic object throw a RuntimeBinderException?
Dynamic throwing Microsoft.CSharp.RuntimeBinder.RuntimeBinderException on private types
以及以下工作:
Dictionary<string, object> values = ((object)timed)
.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(v));
(Get properties of a Dynamic Type)
但我不知道为什么直接访问停止工作。有什么想法吗?谢谢!
发布于 2020-11-16 19:39:58
我发现了它破裂的原因。最初,处理程序和传入的函数都属于同一个程序集。在重构之后,处理程序和调用它的对象被分割成不同的项目和名称空间,从而防止了编译时的绑定。
解决方案是不再传递动态对象,而是传递序列化对象:
OnTime?.Invoke(JsonConvert.SerializeObject(new { name = dto.Name, dto, request }), httpResponseMessage, elapsed);
然后将其消费为:
protected virtual void OnTime(string timed, HttpResponseMessage response, TimeSpan time)
{
var operation = JsonConvert.DeserializeAnonymousType(timed, new { name = string.Empty });
_logger.Write(operation.name);
}
因此,解耦需要额外的序列化步骤,但允许更多地重用代码。
https://stackoverflow.com/questions/64864491
复制相似问题