使用存储在字符串中的 C# 对象初始值设定项语法实例化匿名对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/899962/
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
Instantiating anonymous object using C# object initializer syntax stored in string
提问by DSO
Using the C# object initializer syntax I can instantiate an anonymous object like this:
使用 C# 对象初始值设定项语法,我可以像这样实例化一个匿名对象:
object empData = new { name = "bob", age = 30, salary = 100000 };
But what if I have the initializer stored in a string, e.g.:
但是如果我将初始化程序存储在一个字符串中,例如:
string init = "{ name = \"bob\", age = 30, salary = 100000 }";
Whats the best way of converting this string into an instance of the object?
将此字符串转换为对象实例的最佳方法是什么?
采纳答案by Colin Burnett
Anonymous classes are C# syntactic sugar(see Remarks section here). csc.exe creates a class with private fields and a read/write property with the type inferred from context. All uses of the object are, again, inferred.
匿名类是 C#语法糖(请参阅此处的备注部分)。csc.exe 创建一个具有私有字段的类和一个从上下文推断的类型的读/写属性。再次推断对象的所有用途。
What this means is you cannot create an anonymous class at run time because the CLR sees them no differently than any other class (again, because it is C# syntactic sugar).
这意味着您不能在运行时创建匿名类,因为 CLR 认为它们与任何其他类没有什么不同(同样,因为它是 C# 语法糖)。
So instead:
所以与其:
- Use a
Dictionary<string,object>
- Use JSON.NET, XML or something like it that has some already-defined scheme for parsing a string to get an object. This requires the properties be well-defined, however.
- Use
System.Reflection.Emit
to create the type at run-time, but I see no real benefit to this over just aDictionary<string,object>
- 用一个
Dictionary<string,object>
- 使用 JSON.NET、XML 或类似的东西,它们具有一些已定义的方案来解析字符串以获取对象。然而,这需要明确定义属性。
- 用于
System.Reflection.Emit
在运行时创建类型,但我认为这比仅使用Dictionary<string,object>
I also have concerns of what you're doing because this as a string very likely means to me that you are accepting user input of some kind. Be wary of the security issues in whatever you do.
我也担心你在做什么,因为这作为一个字符串对我来说很可能意味着你正在接受某种类型的用户输入。无论您做什么,都要警惕安全问题。
回答by Mehrdad Afshari
There's no direct easy way to do so. Basically, you have these options:
没有直接简单的方法可以做到这一点。基本上,您有以下选择:
- Parse the string manually.
- Use the C# compiler to compile that object as a part of an assembly and use reflection to figure out the contents.
- (not sure if it's possible, C# 4.0 only): Use C# 4.0 managed compiler classes to parse the expression and infer the stuff.
- 手动解析字符串。
- 使用 C# 编译器将该对象编译为程序集的一部分,并使用反射来找出内容。
- (不确定是否可行,仅限 C# 4.0):使用 C# 4.0 托管编译器类来解析表达式并推断内容。
None of which is ideal in my opinion. I'd consider QueryString like pairs, XML or JSON or some other format that has parsers available out there instead if you have the option and consider storing data in a dictionary instance instead of creating an object for every expression.
在我看来,没有一个是理想的。如果您有选择并考虑将数据存储在字典实例中,而不是为每个表达式创建一个对象,我会考虑使用 QueryString 之类的对、XML 或 JSON 或其他一些具有解析器的格式。
回答by BFree
It's not possible using anonymous types, however you can do it with Reflection Emit using the TypeBuilder class, specifically TypeBuilder.Create(..).
使用匿名类型是不可能的,但是您可以使用 TypeBuilder 类通过反射发射来实现,特别是 TypeBuilder.Create(..)。
http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.createtype.aspx
http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.createtype.aspx
回答by BenAlabaster
I don't think this question answers yours per se, but it will tell you why it's not possible to create anonymous instances of objects using strings in a manner such as you suggest:
我认为这个问题本身并不能回答你的问题,但它会告诉你为什么不可能以你建议的方式使用字符串创建对象的匿名实例:
How do I create and access a new instance of an Anonymous Class passed as a parameter in C#?
Anonymous types don't have any public fields, consequently while you can do this for a named object, it's not so simple to do it for an anonymous type. That said, there's nothing to stop you [as suggested by BFree] using reflection to emit the MSIL for the anonymous type - which isn't exactly straightforward, but isn't impossible either.
匿名类型没有任何公共字段,因此虽然您可以对命名对象执行此操作,但对匿名类型执行此操作并不那么简单。也就是说,没有什么可以阻止您 [如 BFree 所建议的] 使用反射为匿名类型发出 MSIL - 这并不完全简单,但也并非不可能。
回答by Robert Harvey
The best way to do it is to use serialization. But of course, that doesn't use the same string format that you described.
最好的方法是使用序列化。但是,当然,这不使用您描述的相同字符串格式。
Your object initializer does not have to contain constant values.
您的对象初始值设定项不必包含常量值。
string myName="bob";
int myAge=30;
double mySalary=100000;
object empData = new { name = myName, age = myAge, salary = mySalary };
So in your scenario you would have to parse out the individual elements from your string, and perform some conversions on them to coerce them into the types you want.
因此,在您的场景中,您必须从字符串中解析出各个元素,并对它们执行一些转换以将它们强制转换为您想要的类型。
If you are not married to this particular string format, you can serialize and deserialize your objects and accomplish the same thing using XML much more easily.
如果您不习惯这种特定的字符串格式,您可以序列化和反序列化您的对象,并使用 XML 更轻松地完成同样的事情。