使用C#对象初始化语法实例化匿名对象并将其存储在字符串中

14

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

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

但是如果我将初始值存储在一个字符串中,会怎样呢?例如:

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

如何将这个字符串转换为对象的实例?

5个回答

22
匿名类是C#语法糖(请参见此处的备注部分here)。csc.exe会创建一个带有私有字段和可读/可写属性的类,其类型从上下文中推断出来。对象的所有用途都是再次推断的。
这意味着您无法在运行时创建匿名类,因为CLR将它们视为与任何其他类别相同(因为它是C#语法糖)。
所以代替方法:
  • 使用Dictionary<string,object>
  • 使用JSON.NET、XML或类似的东西,它具有一些已定义的方案,用于解析字符串以获取对象。但是,这要求属性被明确定义。
  • 使用System.Reflection.Emit在运行时创建类型,但我认为这并没有比Dictionary<string,object>更大的好处
我也对你正在做的事情有所担忧,因为这个字符串很可能意味着你正在接受某种形式的用户输入。无论你做什么,都要注意安全问题。

啊...你说得对,我知道在编译时生成匿名类,但我的大脑没有将它们联系起来(也许是因为太久没休息了)。而且,你对安全性和用户输入的关注确实很有道理。无论如何,我这么做的原因是因为我调用的 API 接受一个匿名对象。但事实证明,我也可以传递一个 Dictionary<string, object>,所以这解决了我的问题。谢谢。 - dso
我完全同意。我喜欢使用XML,利用反射来创建一些复杂的自定义XML。这不适合每个人,但如果你只是做简单的XML,那么使用.NET XML序列化就足够了:D - pqsk

5

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

您的对象初始化程序不必包含常量值。

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

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

在您的情况下,您需要从字符串中解析出各个元素,并对它们执行一些转换,以将它们强制转换为所需的类型。

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


加1分,因为你在问题的限制之外思考了……现在可能已经很晚了。 - BenAlabaster

5

2

没有直接简单的方法来实现。基本上,你有以下几个选项:

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

在我看来,以上选项都不是理想的选择。如果可以选择,建议考虑像Querystring、XML或JSON等有解析器可用的格式,同时考虑将数据存储在字典实例中,而不是为每个表达式创建一个对象。


1

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

如何在C#中创建和访问作为参数传递的匿名类的新实例?

匿名类型没有任何公共字段,因此虽然您可以为命名对象执行此操作,但对于匿名类型来说并不那么简单。 话虽如此,没有什么能阻止您[如BFree所建议的]使用反射来发出匿名类型的MSIL - 这并不是非常简单,但也不是不可能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接