假设我有这样一个类:
public class User
{
public Guid Id { get; set;}
public DateTime CreationDate { get; set; }
public string Name { get; set; }
public UserGroup Group { get; set; }
}
是否有办法获得所有不属于。net框架的属性类型?在这种情况下,我只想得到UserGroup
?可以吗?
我能想到的最好的东西是:
IEnumerable<Type> types = typeof(User).GetProperties().Where(p => !p.PropertyType.Namespace.StartsWith("System.")).Select(t => t.PropertyType);
但这看起来像一个hack job。对不起,如果dup,找不到类似的东西,抱歉的格式,我已经尽力了。
我认为你所拥有的可能足够可靠,足以满足你的需要。然而,从灵活性/可读性的角度来看,也许最好定义自己的属性类型,可以在属性级别应用,例如
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
{
}
反射总是一种黑客攻击,所以,是的,它感觉像一个hackjob。
但是分析实体,类,必须通过反射来完成。所以你的做法是正确的。
一个陷阱。您自己可以在名称空间"System"中创建自己的类型。那会打乱你的搜索。你也可以分析属性类型的程序集,但是你必须知道所有的。net程序集,这是一个大列表。
你所做的是好的,你可以做这样的事情,然而,并利用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();
}
你的方法有效。我只是想说,您还可以尝试检查在其中定义类型的程序集,例如检查它是否从全局程序集缓存加载。
bool wasLoadedFromAssemblyCache = typeof(T).Assembly.GlobalAssemblyCache;