使用存储在string中的C#对象初始值设定语法实例化匿名对象

时间:2009-05-22 20:57:08

标签: c# dynamic

使用C#对象初始化程序语法我可以像这样实例化一个匿名对象:

object empData = new { name = "bob", age = 30, salary = 100000 };

但是如果我将初始值设定项存储在字符串中,例如:

string init = "{ name = \"bob\", age = 30, salary = 100000 }";

将此字符串转换为对象实例的最佳方法是什么?

5 个答案:

答案 0 :(得分:17)

匿名类是C#syntactic sugar (请参阅备注部分here)。 csc.exe创建一个具有私有字段和读/写属性的类,其类型从上下文推断出来。再次推断出对象的所有用途。

这意味着您无法在运行时创建匿名类,因为CLR看到它们与其他类没有什么不同(同样,因为它是C#语法糖)。

所以相反:

  • 使用Dictionary<string,object>
  • 使用JSON.NET,XML或类似的东西,它具有一些已定义的方案,用于解析字符串以获取对象。但是,这需要明确定义属性。
  • 使用System.Reflection.Emit在运行时创建类型,但我发现这不仅仅是Dictionary<string,object>
  • 的真正好处

我也担心你正在做什么,因为这作为一个字符串很可能意味着你接受某种用户输入。无论你做什么,都要警惕安全问题。

答案 1 :(得分:5)

使用匿名类型是不可能的,但是你可以使用TypeBuilder类使用Reflection Emit,特别是TypeBuilder.Create(..)。

http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.createtype.aspx

答案 2 :(得分:4)

最好的方法是使用序列化。但是,当然,这不会使用您描述的相同字符串格式。

您的对象初始值设定项不必包含常量值。

string myName="bob";
int myAge=30;
double mySalary=100000;

object empData = new { name = myName, age = myAge, salary = mySalary };

因此,在您的场景中,您必须解析字符串中的各个元素,并对它们执行一些转换,以将它们强制转换为您想要的类型。

如果您未与此特定字符串格式结合,则可以更轻松地序列化和反序列化对象并使用XML完成相同的操作。

答案 3 :(得分:2)

没有直接简单的方法可以做到这一点。基本上,您有以下选择:

  1. 手动解析字符串。
  2. 使用C#编译器将该对象编译为程序集的一部分,并使用反射来计算内容。
  3. (不确定是否可能,仅限C#4.0):使用C#4.0托管编译器类来解析表达式并推断出内容。
  4. 在我看来,这些都不是理想的。如果您有选项并考虑将数据存储在字典实例中而不是为每个表达式创建一个对象,我会认为QueryString就像对,XML或JSON或其他具有解析器的格式。

答案 4 :(得分:1)

我不认为这个问题本身会回答你的问题,但它会告诉你为什么用你建议的方式使用字符串创建对象的匿名实例是不可能的:

How do I create and access a new instance of an Anonymous Class passed as a parameter in C#?

匿名类型没有任何公共字段,因此当您可以为命名对象执行此操作时,对匿名类型执行此操作并不是那么简单。也就是说,没有什么可以阻止你(正如BFree所建议的那样)使用反射为匿名类型发出MSIL - 这不是很简单,但也不是不可能。