【问题标题】:C# Detecting AnonymousType new{name=value,} and convert into Dictionary<string,object>C# 检测 AnonymousType new{name=value,} 并转换为 Dictionary<string,object>
【发布时间】:2009-07-17 15:53:59
【问题描述】:

我需要检测一个对象是否是匿名创建的,比如 new{name=value,}

如果它是 AnonymousType,则应将其属性名称/值添加到

Dictionary<string,object>

这是我自己破解的:

var name="name";

var obj = new { name = new object(), };

var lookup = new Dictionary<string,object>();


if(obj.GetType().Name.StartsWith("<>f__AnonymousType"))
{
    foreach (var property in obj.GetType().GetProperties())
    {
        lookup[property.Name] = property.GetValue(obj, null);
    }
}
else
{
    lookup[name]=obj;
}

我想知道是否有更好/更快的方法来检测 AnonymousTypes, 或者是否有更好/更快的方法将对象的属性名称/值转储到

Dictionary<string,object>

【问题讨论】:

  • 你想用这个来完成什么?不管是什么,都必须有更好的方法来做到这一点。

标签: c# .net


【解决方案1】:

要获取对象的所有属性及其值到 Dictionary,您可以将 Linq 的强大功能与具有反射的对象结合起来。

你可以使用Enumerable.ToDictionary方法:

var dic = obj.GetType()
             .GetProperties()
             .ToDictionary(p => p.Name,  p=> p.GetValue(obj, null));

这将返回一个Dictionary&lt;string, object&gt;

【讨论】:

  • 问题是如果他一开始就可以使用字典,除非 Linq 对该查询进行一些疯狂的缓存,否则它会快得多,在这种情况下,它“只会”快得多.
  • 如果我看到像“GenericEqualityComparer”这样的“内在”属性,而不是我明确声明的属性怎么办?我试过GetProperties(BindingFlags.DeclaredOnly)
  • 奇怪,没关系 - 我发现使用此反射的方法(本身在对象扩展中)最终使用转换后的结果调用自身,因此我的扩展被调用在对象上,然后在结果上调用字典。
【解决方案2】:

使用新的集合对象初始化语法而不是匿名类型:

var obj = new Dictionary<string, object>()
{
    { "Name", t.Name },
    { "Value", t.Value }
};

【讨论】:

    【解决方案3】:

    检测匿名类型有点困难;至少它取决于语言! VB 匿名类型看起来与 C# 匿名类型不同。我会怀疑在匿名类型上行为不同的逻辑。您可能会检查 [CompilerGenerated],但请注意,它不仅仅意味着“匿名类型”——还有其他人这样做。

    就个人而言,在这种情况下我不会区分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多