2009-05-22 54 views
7

使用C#对象初始化语法我可以实例化一个匿名对象是这样的:如果我有存储在一个字符串,如初始化实例化使用C#对象初始化语法匿名对象存储在字符串

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

但是什么:

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

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

回答

16

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

这意味着你不能在运行时创建一个匿名类,因为CLR认为它们与其他类没有区别(再次,因为它是C#语法糖)。

所以不是:

  • 使用Dictionary<string,object>
  • 使用JSON.NET,XML或类似的东西具有用于解析字符串,得到一个对象有的已定义的方案。然而,这要求属性必须明确。
  • 使用System.Reflection.Emit创建在运行时的类型,但我看不出有什么实际的好处这在短短Dictionary<string,object>

我也有你在做什么,因为这是一个字符串很可能手段的担忧对我来说,你正在接受某种用户输入。无论你做什么,都要小心安全问题。

+0

啊......你是对的,我知道在编译时生成的匿名类,但我的大脑并没有建立连接(猜测长周末过期)。此外,您对安全和用户输入的担忧绝对有效。无论如何,我这样做的原因是因为我调用的API使用了匿名对象。但事实证明,我也可以传入Dictionary ,以便为我解决问题。谢谢。 – DSO 2009-05-22 22:55:02

2

没有直接简单的方法来做到这一点。基本上,你有这些选项:

  1. 手动解析字符串。
  2. 使用C#编译器将该对象编译为程序集的一部分,并使用反射来计算内容。
  3. (不确定是否可能,仅C#4.0):使用C#4.0托管编译器类来解析表达式并推断出这些内容。

在我看来,这些都不是理想的。我认为QueryString就像对,XML或JSON或其他一些有解析器可用的格式,如果你有选择,并考虑将数据存储在字典实例中而不是为每个表达式创建一个对象。

1

我不认为这个问题的答案你本身,而是它会告诉你它为什么不能创建使用字符串的方式,对象的匿名情况下,如你的建议:

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

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

3

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

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

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

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

所以在你的情况下,你必须从你的字符串解析出的各个元素,并对其进行一些转换强迫他们你想要的类型。

如果你不是这种特定字符串格式的结合体,你可以序列化和反序列化你的对象,并且使用XML更容易完成同样的事情。

+0

+1问题范围之外的思考......它一定是迟到了 – BenAlabaster 2009-05-22 21:12:32