A dictionary where value is an anonymous type in C#

前端 未结 5 535
鱼传尺愫
鱼传尺愫 2020-12-01 04:26

Is it possible in C# to create a System.Collections.Generic.Dictionary where TKey is unconditioned class and TValue

相关标签:
5条回答
  • 2020-12-01 04:48

    You can't declare such a dictionary type directly (there are kludges but these are for entertainment and novelty purposes only), but if your data is coming from an IEnumerable or IQueryable source, you can get one using the LINQ ToDictionary() operator and projecting out the required key and (anonymously typed) value from the sequence elements:

    var intToAnon = sourceSequence.ToDictionary(
        e => e.Id,
        e => new { e.Column, e.Localized });
    
    0 讨论(0)
  • 2020-12-01 04:49

    You can do a refection

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 04:52

    As itowlson said, you can't declare such a beast, but you can indeed create one:

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

    It's not clear why you'd actually want to use code like this.

    0 讨论(0)
  • 2020-12-01 04:52

    If you would like to initialize an empty dictionary you could do something like the this:

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

    Basically you just need an empty enumerable with a tuple that has the types you want to use in your final anonymous types and then you can get an empty dictionary that is typed the way you'd like.

    If you wanted to you could name the types in the tuple as well:

    var emptyDict = Enumerable
                .Empty<(int anInt, string aString)>()
                .ToDictionary(
                    x => new { Id = x.anInt },
                    x => new { Column = x.aString, Localized = x.aString});
    
    0 讨论(0)
  • 2020-12-01 05:00

    I think ASP.NET MVC didn't exit at the time this question was made. It does convert anonymous objects to dictionaries internally.

    Just take a look at the HtmlHelper class, for example. The method that translates objects to dictionaries is the AnonymousObjectToHtmlAttributes. It it's specifc to MVC and returns an RouteValueDictionary, however.

    If you want something more generic, try this:

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

    One intersting advatages of this implementation is that it returns an empty dictionary for null objects.

    And here's one generic version:

    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))
            );
    }
    
    0 讨论(0)
提交回复
热议问题