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

这样的事情:

new { ID = 1, Name = new { Column = "Dollar", Localized = "Доллар" } }
有帮助吗?

解决方案

你不能直接声明这样的字典类型(有kludges但这些仅用于娱乐和新颖目的),但如果你的数据来自IEnumerable或IQueryable源,你可以使用LINQ ToDictionary运算符得到一个并从序列元素中突出显示所需的键和(匿名类型)值:

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

其他提示

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 = "Доллар" });
}

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

我认为ASP.NET MVC在提出这个问题的时候没有退出。它确实在内部将匿名对象转换为字典。

只需查看 HtmlHelper,例。将对象转换为字典的方法是 AnonymousObjectToHtmlAttributes 。它是MVC的特定,然后返回RouteValueDictionary

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

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

此实现的一个主要优点是它返回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))
        );
}

你可以做一个反思

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;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top