.net 有没有办法将动态或匿名对象转换为强类型声明的对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17101190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to convert a dynamic or anonymous object to a strongly typed, declared object?
提问by ProfK
If I have a dynamic object, or anonymous object for that matter, whose structure exactly matches that of a strongly typed object, is there a .NET method to build a typed object from the dynamic object?
如果我有一个动态对象或匿名对象,其结构与强类型对象的结构完全匹配,是否有 .NET 方法从动态对象构建类型化对象?
I know I can use a LINQ dynamicList.Select(dynamic => new Typed { .... }type thing, or I can use Automapper, but I'm wondering if there is not something specially built for this?
我知道我可以使用 LINQdynamicList.Select(dynamic => new Typed { .... }类型的东西,或者我可以使用 Automapper,但我想知道是否没有专门为此构建的东西?
回答by Grimace of Despair
You could serialize to an intermediate format, just to deserialize it right thereafter. It's not the most elegant or efficient way, but it might get your job done:
您可以序列化为中间格式,然后立即反序列化。这不是最优雅或最有效的方式,但它可能会完成您的工作:
Suppose this is your class:
假设这是你的班级:
// Typed definition
class C
{
public string A;
public int B;
}
And this is your anonymous instance:
这是您的匿名实例:
// Untyped instance
var anonymous = new {
A = "Some text",
B = 666
};
You can serialize the anonymous version to an intermediate format and then deserialize it again to a typed version.
您可以将匿名版本序列化为中间格式,然后再次将其反序列化为类型化版本。
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var json = serializer.Serialize(anonymous);
var c = serializer.Deserialize<C>(json);
Note that this is in theory possible with any serializer/deserializer (XmlSerializer, binary serialization, other json libs), as long as the roundtrip is symmetric.
请注意,只要往返是对称的,理论上这对于任何序列化器/反序列化器(XmlSerializer、二进制序列化、其他 json 库)都是可行的。
回答by Tengiz
Your question comes down to the question: can I convert one staticallytyped variable into another staticallytyped variable (from different inheritance chains)?and the answer, obviously, is No.
您的问题归结为一个问题:我可以将一个静态类型变量转换为另一个静态类型变量(来自不同的继承链)吗?显然,答案是否定的。
Why does your question come down to the above question?
为什么你的问题归结为上述问题?
- Dynamic type usage compilesinto using the Object type with reflection.
- Your code receives Object in reality, that (in reality) contains value from one particular static type.
- 动态类型用法编译为使用带有反射的 Object 类型。
- 您的代码实际上接收 Object,它(实际上)包含来自一种特定静态类型的值。
So, in fact, your code is dealing with the statically typed value, assigned to the Object, and treated as Dynamic at compile time. Therefore, the only case when you can convert one statically typed value into another [without reflection] is when they are part of the same inheritance chain. Otherwise, you are bound to using reflection explicitly (written by you) or implicitly (written by MS with Dynamic usage).
因此,实际上,您的代码正在处理静态类型的值,分配给对象,并在编译时被视为动态。因此,您可以将一个静态类型值转换为另一个 [无需反射] 的唯一情况是它们是同一继承链的一部分。否则,您必须显式(由您编写)或隐式(由 MS 使用动态用法编写)使用反射。
In other words, the following code will work at runtimeonly if the value assigned to the dynamic is derived from Person or is Person itself (otherwise the cast to Person will throw an error):
换句话说,仅当分配给动态的值是从 Person 派生的或者是 Person 本身时,以下代码才会在运行时工作(否则对 Person 的强制转换会抛出错误):
dynamic dPerson = GetDynamicPerson();
Person thePerson = (Person)dPerson;
That's pretty much it.
差不多就是这样。
Fair to mention, you can copy the values byte by byte with unsafe code accessing the memory addresses (like in C++), but that to me is nothing better than reflection.
公平地说,您可以使用访问内存地址的不安全代码(如在 C++ 中)逐字节复制值,但这对我来说没有比反射更好的了。
回答by jherax
Here we can convert an anonymous object to Dictionary
在这里我们可以将匿名对象转换为 Dictionary
Dictionary<string, object> dict =
obj.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(obj, null));
Also you can cast an object using LINQ:
您也可以使用LINQ投射对象:
List<MyType> items = anonymousType.Select(t => new MyType(t.Some, t.Other)).ToList();
回答by russbishop
If your object inherits from MarshalByRefObject you can use RealProxy.
如果您的对象继承自 MarshalByRefObject,您可以使用 RealProxy。
Another alternative is to use Reflection but you may be limited by stuff not marked virtual and/or have to use interfaces. You could also have it copy the values, assuming the properties are writable and the empty constructor works for your case.
另一种选择是使用反射,但您可能会受到未标记为虚拟和/或必须使用接口的内容的限制。您也可以让它复制值,假设属性是可写的并且空构造函数适用于您的情况。
The actual answer to your question is no, there is no automatic way to treat a dynamic object as a specific type unless it is an instance of that type, nor is there any automatic facility to copy the values from a dynamic/anonymous object into an instance of a named class.
您问题的实际答案是否定的,除非它是该类型的实例,否则没有自动方法将动态对象视为特定类型,也没有任何自动工具将值从动态/匿名对象复制到命名类的实例。
The runtime has no idea what is going on in the constructor or how the class is implemented internally, so any such facility would blow type safety out of the water. The whole point of dynamic is to allow duck typing/runtime dispatch/etc.
运行时不知道构造函数中发生了什么,或者类是如何在内部实现的,所以任何这样的设施都会使类型安全性大打折扣。动态的全部意义在于允许鸭子输入/运行时调度/等。
edit: If I misunderstood the question let me know, but I am assuming you want to treat a dynamic object as if it were an instance of SomeType.
编辑:如果我误解了这个问题,请告诉我,但我假设您想将动态对象视为 SomeType 的实例。
In my own projects, I've used an Object Mapper class for this where it matches up the property names for writable properties and identical or coercible types so at least I didn't have to write 10,000 lines of boilerplate, though my source wasn't dynamic so I used Reflection.Emit/DynamicMethod to greatly speed it up.
在我自己的项目中,我为此使用了一个 Object Mapper 类,它匹配可写属性和相同或可强制类型的属性名称,因此至少我不必编写 10,000 行样板,尽管我的源代码是“ t dynamic 所以我使用了 Reflection.Emit/DynamicMethod 来大大加快它的速度。

