سؤال

هل من الممكن في 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 . ذلك انها 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)
        );
}

واحد ادفاتاغيس يضيع هذا التنفيذ هو أن تقوم بإرجاع القاموس فارغة للكائنات 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