字典,其中值是在C#匿名类型(A dictionary where value is an anonymous type in C#)

是否有可能在C#创建一个System.Collections.Generic.Dictionary<TKey, TValue> ,其中TKey是无条件的类和TValue -与多个属性的一个匿名类,例如-数据库列名和它的本地化名称。

事情是这样的:

new { ID = 1, Name = new { Column = "Dollar", Localized = "Доллар" } }

Answer 1:

您不能直接宣布这样一个字典类型(也有组装机,但这些只用于娱乐和新奇的目的),但如果你的数据从一个IEnumerable或IQueryable的源来了,你可以使用LINQ ToDictionary运营商出突起送一所需要的密钥和(匿名键入)值从该序列元素:

var intToAnon = sourceSequence.ToDictionary(
    e => e.Id,
    e => new { e.Column, e.Localized });


Answer 2:

作为itowlson ,你不能声明这样的野兽,但你的确可以创建一个:

static IDictionary<TKey, TValue> NewDictionary<TKey, TValue>(TKey key, TValue value)
{
    return new Dictionary<TKey, TValue>();
}

static void Main(string[] args)
{
    var dict = NewDictionary(new {ID = 1}, new { Column = "Dollar", Localized = "Доллар" });
}

为什么你真的想使用这样的代码目前尚不清楚。



Answer 3:

我认为ASP.NET MVC没有在这个问题发生的时间退出。 它内部的匿名对象转换成字典。

只是来看看HtmlHelper ,例如。 该翻译对象字典的方法是AnonymousObjectToHtmlAttributes 。 这是specifc到MVC,并返回一个RouteValueDictionary ,但是。

如果你想要更多的东西通用的,试试这个:

public static IDictionary<string,object> AnonymousObjectToDictionary(object obj)
{
    return TypeDescriptor.GetProperties(obj)
        .OfType<PropertyDescriptor>()
        .ToDictionary(
            prop => prop.Name,
            prop => prop.GetValue(obj)
        );
}

这个实现的一个野趣advatages是,它返回一个空的字典null的对象。

而这里的一个通用版本:

public static IDictionary<string,T> AnonymousObjectToDictionary<T>(
    object obj, Func<object,T> valueSelect
)
{
    return TypeDescriptor.GetProperties(obj)
        .OfType<PropertyDescriptor>()
        .ToDictionary<PropertyDescriptor,string,T>(
            prop => prop.Name,
            prop => valueSelect(prop.GetValue(obj))
        );
}


Answer 4:

你可以做一个恢复体力

public static class ObjectExtensions
{
    /// <summary>
    /// Turn anonymous object to dictionary
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public static IDictionary<string, object> ToDictionary(this object data)
    {
        var attr = BindingFlags.Public | BindingFlags.Instance;
        var dict = new Dictionary<string, object>();
        foreach (var property in data.GetType().GetProperties(attr))
        {
            if (property.CanRead)
            {
                dict.Add(property.Name, property.GetValue(data, null));
            }
        }
        return dict;
    }
}