一个字典,其中value是C#中的匿名类型

时间:2009-10-24 23:43:19

标签: c# .net linq dictionary anonymous-types

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

这样的事情:

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

5 个答案:

答案 0 :(得分:41)

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

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

答案 1 :(得分:18)

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

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

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

答案 2 :(得分:4)

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

例如,请查看HtmlHelper class。将对象转换为字典的方法是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))
        );
}

答案 3 :(得分:3)

你可以做一个反思

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;
    }
}

答案 4 :(得分:0)

如果您想初始化一个空字典,可以执行以下操作:

def createQuiz():
    quiz = []
    for i in range(2):
        quiz.append(str(i+1) + ') ' + input('Please input Question ' + str(i+1) + ':\n'))
        for j in range(4):
            quiz.append(chr(97+j) + '. ' + input('Please input option ' + str(j+1) + ':\n'))
        quiz.append('Answer: ' + input('Please input Answer(A,B,C,D):\n'))
    return quiz


def saveQuiz():
    with open('quiz.txt', 'w') as file:
        for i in createQuiz():
            file.write(i)
            file.write('\n')


def menu():
        userinput = int(input())
        if userinput == 1:
            createQuiz()
        elif userinput == 2:
            saveQuiz()

基本上,您只需要一个具有元组的空枚举,该元组具有要在最终匿名类型中使用的类型,然后您可以获取一个空字典,该空字典将按您的方式键入。

如果您愿意,也可以在元组中命名类型:

var emptyDict = Enumerable
    .Empty<(int, string)>()
    .ToDictionary(
         x => new { Id = x.Item1 }, 
         x => new { Column = x.Item2, Localized = x.Item2});