使用Reflection获取自定义属性类型

时间:2013-04-30 09:38:01

标签: c# .net reflection

假设我有一个类(类似这样):

public class User
{
   public Guid Id { get; set;}
   public DateTime CreationDate { get; set; }
   public string Name { get; set; }
   public UserGroup Group { get; set; } 
}

是否有办法获取不属于.NET Framework的所有属性类型。 所以在这种情况下我想只获得UserGroup?这可能吗?

我能想到的最好的事情是:

IEnumerable<Type> types = typeof(User).GetProperties().Where(p => !p.PropertyType.Namespace.StartsWith("System.")).Select(t => t.PropertyType);

但这看起来像是一个黑客工作。对不起,如果是dup,找不到那样的东西,对不起格式化,请尽力。

4 个答案:

答案 0 :(得分:1)

我认为你所拥有的东西可能足以满足你的需求。但是,从灵活性/可读性的角度来看,最好定义一个你可以在属性级别应用的属性类型,即

public class User
{
    public Guid Id { get; set; }
    public DateTime CreationDate { get; set; }
    public string Name { get; set; }
    [CustomProperty]
    public UserGroup Group { get; set; }
}

然后,您可以使用反射来查询具有此属性的所有属性。这样您就可以包含/排除任何属性。


  

抱歉,我忘了提及我无法修改域名实体。 (无法添加属性)。

您可以使用MetadataType向基类添加属性,例如

class UserMetadata
{
    ...
    [CustomProperty]
    public UserGroup Group { get; set; }
}

[MetadataType(typeof(UserMetadata)]
public class DomainUser : User
{
}

答案 1 :(得分:1)

反思总是某种黑客攻击,所以是的,感觉像是一个黑客。

但分析实体,班级,必须用反思来完成。所以你正在以正确的方式做到这一点。

一个陷阱。您自己可以在名称空间“System”中创建自己的类型。这会搞砸你的搜索。您还可以分析属性类型的汇编,但是您必须知道所有.NET程序集,这是一个很大的列表。

答案 2 :(得分:0)

你做得很好,你可以这样做,然后使用Except方法。

public static Type[] GetNonSystemTypes<T>()
{
  var systemTypes = typeof(T).GetProperties().Select(t => t.PropertyType).Where(t => t.Namespace == "System");
  return typeof(T).GetProperties().Select(t => t.PropertyType).Except(systemTypes).ToArray();
}

答案 3 :(得分:0)

你的方法有效。我只想投入,您也可以尝试检查已定义类型的程序集,例如检查它是否是从全局程序集缓存中加载的。

bool wasLoadedFromAssemblyCache = typeof(T).Assembly.GlobalAssemblyCache;