我有一个IEnumerable<KeyValuePair<string,string>>
,理想情况下,我想要一个匿名对象,它将键作为属性名称,值作为属性值。
我尝试了各种选择表达式(其中没有一个甚至编译过......)和使用ExpandoObject
的方法(见下文),但没有成功。有没有办法做到这一点?如果可能的话,我想避免对集合进行额外的显式迭代(即使用某种LINQ语句完成所有操作)。
这是我到目前为止所尝试过的。我希望它也澄清了我想要做的事情:
var kvps = getProps(); // returns IEnumerable<KeyValuePair<string,string>>
dynamic o = new ExpandoObject();
foreach (var kvp in kvps)
{
o.Add(kvp);
}
这在编译时没问题,但在运行时我得到一个YSOD说明'System.Dynamic.ExpandoObject'不包含'添加'的定义 - 我猜它有效在编译时,因为o
是动态的,所以编译器无法知道自实例化以来是否已向其添加了方法.Add()
。奇怪的是,MSDN documenation page for ExpandoObject .Add()
上的内容被列为几种“明确实现的接口方法”之一。
我没有必要把它变成一个动态对象 - 我只需要根据键值对的键和值获得具有属性名称和值的东西。
更新:嗯,这很尴尬。事实证明这也是一个XY问题。
我正在尝试使用ASP.NET MVC的内置功能将此呈现给JSON,只需在我的控制器中返回Json(data)
即可。答案都能很好地完成我第一次提出的问题,但是当我将这个对象传递给data
时,我仍然无法得到我想要的东西:
// What I get:
[
{ Key: 'firstkey', Value: 'FirstValue' },
{ Key: 'secondKey', Value: 'secondValue' }
]
// What I want:
{ firstKey: 'FirstValue', secondKey: 'secondValue' }
显然,添加了相关属性的ExpandoObject
没有删除它 - 它在渲染之前被转换为字典...
答案 0 :(得分:6)
填充时,您需要将ExpandoObject
用作IDictionary<string, object>
:
var kvps = getProps(); // returns IEnumerable<KeyValuePair<string,string>>
IDictionary<string, object> o = new ExpandoObject();
foreach (var kvp in kvps)
{
// Or use Add(kvp.Key, kvp.Value), if you want
o[kvp.Key] = kvp.Value;
}
dynamic d = o;
// Now you can use the properties
答案 1 :(得分:4)
ExpandoObject
明确实现IDictionary<string, object>
- 因此您需要先将其强制转换为:
var kvps = getProps();
dynamic o = new ExpandoObject();
var dict = o as IDictionary<string, object>;
foreach (var kvp in kvps)
{
dict.Add(kvp.Key, kvp.Value);
}
现在您可以按预期使用o
:
var example = o.YourKey;
我正在尝试使用ASP.NET MVC的内置功能将此呈现给JSON,只需在我的控制器中返回Json(数据)即可。
有趣。
为此,您序列化字典,而不是ExpandoObject。 MVC 3的JSON序列化器已经用字典做了。您所要做的就是将IEnumerable<KeyValuePair<string, object>>
转换为字典:
var kvps = getProps();
var dictionary = kvps.ToDictionary(k => k.Key, v => v.Value);
return Json(dictionary, JsonRequestBehavior.AllowGet); //take out allow get if you don't need it.
无需动态。
答案 2 :(得分:1)
我认为你必须将你的expando对象转换为IDictionary并调用Add(string,object)