简体   繁体   中英

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. So in this case I want to get only 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.

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

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.

What you have done is fine, you could do something like this however and make use of the Except method.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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