我意识到这个问题已经得到解答,但我使用了不同的方法,并认为它可能值得分享。另外,我觉得我的方法可能会产生不必要的开销。但是,我无法观察或计算在我们观察到的负载下发生的任何糟糕的事情。我正在寻找有关此方法的任何有用反馈。
使用动态的问题是您不能直接将任何函数附加到动态对象。您必须每次都使用可以找出您不想弄清楚的作业的东西。
在计划这个简单的解决方案时,我查看了在尝试重新键入类似对象时有效的中介是什么。我发现二进制数组、字符串(xml、json)或硬编码转换(IConvertable)是常用的方法。由于代码可维护性因素和懒惰,我不想进行二进制转换。
我的理论是 Newtonsoft 可以通过使用字符串中介来做到这一点。
作为一个缺点,我相当肯定在将字符串转换为对象时,它将通过在当前程序集中搜索具有匹配属性的对象来使用反射,创建类型,然后实例化属性,这需要更多反射。如果属实,所有这些都可以被认为是可避免的开销。
C#:
//This lives in a helper class
public static ConvertDynamic<T>(dynamic data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
//Same helper, but in an extension class (public static class),
//but could be in a base class also.
public static ToModelList<T>(this List<dynamic> list)
{
List<T> retList = new List<T>();
foreach(dynamic d in list)
{
retList.Add(ConvertDynamic<T>(d));
}
}
话虽如此,这适合我组合的另一个实用程序,它可以让我将任何对象变成动态对象。我知道我必须使用反射来正确地做到这一点:
public static dynamic ToDynamic(this object value)
{
IDictionary<string, object> expando = new ExpandoObject();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
expando.Add(property.Name, property.GetValue(value));
return expando as ExpandoObject;
}
我必须提供那个功能。分配给动态类型变量的任意对象不能转换为 IDictionary,并且会破坏 ConvertDynamic 函数。要使用此函数链,必须提供 System.Dynamic.ExpandoObject 或 IDictionary 的动态。