2010-11-05 33 views
3

我有一个List<CustomObject> 其中有3个属性 A,B,C 和我需要的是这样的结果看起来像列表<T>到词典

Dictionary<string,object> 
(Property name) A = Value of A 
(Property name) B = Value of B 
(Property name) C = Value of C 

PLS建议名单进行改造,以词典...

+0

我会让它成为Dictionary '。 – leppie 2010-11-05 15:16:07

+0

耶没有问题...我正在寻找sloution – chugh97 2010-11-05 15:17:17

+0

IIRC我发布了解决方案(使用Reflection.Emit)在另一个问题。很久以前,我现在不记得这个链接。如果我找到它会发布。 – leppie 2010-11-05 15:17:31

回答

5
CustomObject instance = new CustomObject(); 
var dict = instance.GetType().GetProperties() 
    .ToDictionary(p => p.Name, p => p.GetValue(instance, null)); 
+0

你需要'instance.GetType()'使它工作任何类型,其他相当不错的'单行':) – leppie 2010-11-05 15:26:53

+0

@leppie - 是的,这是一个更好的方式,谢谢。 – Lee 2010-11-05 15:28:19

0

如果我理解正确,你想做什么,你必须使用对CustomObject reflrecion获得的属性名称,然后简单地创建词典:

dic.add(propertyName,value);

+0

非常无聊,很慢:) – leppie 2010-11-05 15:25:37

2

我找到了代码:)原文为here

static T CreateDelegate<T>(this DynamicMethod dm) where T : class 
{ 
    return dm.CreateDelegate(typeof(T)) as T; 
} 

static Dictionary<Type, Func<object, Dictionary<string, object>>> cache = 
    new Dictionary<Type, Func<object, Dictionary<string, object>>>(); 

static Dictionary<string, object> GetProperties(object o) 
{ 
    var t = o.GetType(); 

    Func<object, Dictionary<string, object>> getter; 

    if (!cache.TryGetValue(t, out getter)) 
    { 
    var rettype = typeof(Dictionary<string, object>); 

    var dm = new DynamicMethod(t.Name + ":GetProperties", rettype, 
     new Type[] { typeof(object) }, t); 

    var ilgen = dm.GetILGenerator(); 

    var instance = ilgen.DeclareLocal(t); 
    var dict = ilgen.DeclareLocal(rettype); 

    ilgen.Emit(OpCodes.Ldarg_0); 
    ilgen.Emit(OpCodes.Castclass, t); 
    ilgen.Emit(OpCodes.Stloc, instance); 

    ilgen.Emit(OpCodes.Newobj, rettype.GetConstructor(Type.EmptyTypes)); 
    ilgen.Emit(OpCodes.Stloc, dict); 

    var add = rettype.GetMethod("Add"); 

    foreach (var prop in t.GetProperties(
     BindingFlags.Instance | 
     BindingFlags.Public)) 
    { 
     ilgen.Emit(OpCodes.Ldloc, dict); 

     ilgen.Emit(OpCodes.Ldstr, prop.Name); 

     ilgen.Emit(OpCodes.Ldloc, instance); 
     ilgen.Emit(OpCodes.Ldfld, prop); 
     ilgen.Emit(OpCodes.Castclass, typeof(object)); 

     ilgen.Emit(OpCodes.Callvirt, add); 
    } 

    ilgen.Emit(OpCodes.Ldloc, dict); 
    ilgen.Emit(OpCodes.Ret); 

    cache[t] = getter = 
     dm.CreateDelegate<Func<object, Dictionary<string, object>>>(); 
    } 

    return getter(o); 
} 

对于给定类型:现在综观代码(没有测试)有可能需要:

class Foo 
{ 
    public string A {get;} 
    public int B {get;} 
    public bool C {get;} 
} 

它产生一个代表等效于:

(Foo f) => new Dictionary<string, object> 
    { 
    { "A", f.A }, 
    { "B", f.B }, 
    { "C", f.C }, 
    }; 

声明对值类型进行特殊处理(而不仅仅是castclass)。为读者锻炼。

+0

有趣。我喜欢。 – Hath 2010-11-05 15:31:58

+0

@Hath:我被迫为翻译/全球化系统编写它,不得不快速反映WinForm控件。 :) – leppie 2010-11-05 15:36:59

+0

真棒!我刚刚开始用这种方式编写代码,但你已经设法做得更快:)绝对是尽可能快的方法:)尽管可能不像LINQ那样优雅:) – luckyluke 2010-11-05 15:38:45

相关问题