7

我有一个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”不包含“Add”的定义- 我猜它在编译时有效,因为o它是动态的,所以编译器不知道如果.Add()自实例化以来已将方法添加到其中。奇怪的是,在MSDN 文档页面上 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添加了相关属性的 an 并没有削减它 - 它在渲染之前被强制转换为字典......

4

3 回答 3

7

您需要在填充它时使用它ExpandoObjectIDictionary<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
于 2012-06-25T14:36:18.903 回答
6

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(data)。

有趣的。

为此,您序列化一个字典,而不是一个 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.

不需要动态。

于 2012-06-25T14:38:00.570 回答
1

我认为您必须将 expando 对象转换为 IDictionary 并调用 Add(string, object)

于 2012-06-25T14:37:54.203 回答