简体   繁体   English

使用反射获取自定义属性类型

[英]Get custom property types using Reflection

Suppose I have a class (something like this): 假设我有一堂课(类似这样):

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

Is there a way get all property types that are not part of the .NET Framework. 有没有办法获取不属于.NET Framework的所有属性类型。 So in this case I want to get only UserGroup ? 所以在这种情况下,我只想获取UserGroup Is that possible ? 那可能吗 ?

The best thing I can come up with is something like: 我能想到的最好的事情是:

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

But this looks like a hack-job. 但是,这看起来像是骇客工作。 Sorry if dup, couldn't find anything like that, and sorry for the formatting, did my best. 抱歉,dup找不到类似的内容,对于格式设置感到抱歉,我已尽力而为。

I think what you have is probably reliable enough for what you want. 我认为您所拥有的可能足以满足您的需求。 However, from a flexibility/readability point of view maybe it would be better to define your own attribute type which you could apply at property level ie 但是,从灵活性/可读性的角度来看,最好定义自己的属性类型,然后将其应用于属性级别,即

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

You could then use reflection to query all the properties which have this attribute. 然后,您可以使用反射来查询具有此属性的所有属性。 This would give you the ability to include/exclude any properties. 这将使您能够包含/排除任何属性。


Sorry I forgot to mention that I can't modify the domain entities. 抱歉,我忘了提到我无法修改域实体。 (can't add an attribute). (无法添加属性)。

You can use the MetadataType to add attributes to a base class eg 您可以使用MetadataType将属性添加到基类,例如

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

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

Reflection is always some kind of hacking, so yes, it FEELS like a hackjob. 反射总是某种黑客行为,所以是的,它感觉就像黑客一样。

But analyzing the entity, the class, will have to be done with reflection. 但是分析实体(类)必须反思。 So you are doing it the correct way. 因此,您正在按照正确的方式进行操作。

One pitfall. 一个陷阱。 You yourself are able to create your own types inside a namespace "System". 您自己可以在名称空间“系统”内创建自己的类型。 That would mess up your search. 那会打乱您的搜索。 You also could also analyze then Assembly of the property type, but then you have to know of all .NET assemblies, which is a big list. 您还可以分析属性类型的Assembly,但随后您必须了解所有.NET程序集,这是一个很大的列表。

What you have done is fine, you could do something like this however and make use of the Except method. 您所做的一切都很好,但是您可以执行类似的操作并使用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();
}

Your approach works. 您的方法有效。 I would just throw in that you could also try to check the Assembly the type was defined in, and for example check if it was loaded from the global assembly cache. 我只想提出一下,您还可以尝试检查定义类型的Assembly,例如,检查是否从全局程序集缓存中加载了该类型。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM