C# 使用反射从接口获取类型
鉴于以下类型C# 使用反射从接口获取类型,c#,.net,reflection,C#,.net,Reflection,鉴于以下类型 private class MyTestDummyClassValidationDef : ValidationDef<MyTestDummyClass> { ... } public class ValidationDef<T> : IValidationDefinition<T>, IConstraintAggregator, IMappingSource where T : class {
private class MyTestDummyClassValidationDef : ValidationDef<MyTestDummyClass>
{
...
}
public class ValidationDef<T> : IValidationDefinition<T>, IConstraintAggregator, IMappingSource where T : class
{ }
public interface IMappingSource
{
IClassMapping GetMapping();
}
public interface IClassMapping
{
Type EntityType { get; }
...
}
私有类MyTestDummyClassValidationDef:ValidationDef
{
...
}
公共类ValidationDef:IValidationDefinition、IConstraintAggregator、IMappingSource其中T:class
{ }
公共接口IMappingSource
{
IClassMapping GetMapping();
}
公共接口IClassMapping
{
类型EntityType{get;}
...
}
在配置时,我知道所有ValidationDefinitions;上面的“MyTestDummyClassValidationDef”就是这样一个定义的示例
如果遵循继承/实现轨迹,那么最后是一个EntityType,它由IClassMapping公开
作为验证基础结构的一部分,可能会要求各种对象进行自我验证。对象可能有也可能没有为其定义ValidationDef,这可能是因为验证不适用于该对象,或者定义尚未编写。如果要求对象验证自身,但没有定义,则会发生运行时错误
所以,我试图得到一个EntityTypes列表,我可以在运行时使用它来检查。如果要求验证自身的对象不在列表中,那么我可以避免否则会发生的运行时错误
我该怎么做
干杯,贝里尔 我正在寻找的代码 公共实体验证器(验证器引擎验证器引擎,IEnumerable defTypes){ ValidationDefs=新列表(); foreach(defTypes中的变量类型) { 如果(type.BaseType.GetGenericTypeDefinition()!=typeof(ValidationDef))继续; var mappingSource=(IMappingSource)Activator.CreateInstance(类型); var entityType=mappingSource.GetMapping().entityType; ValidationDefs.Add(entityType); }
如果我理解正确,您希望调用方法的显式接口实现,即实现接口方法且仅在接口本身中可见而在类中不可见的方法 为此,首先检索
IClassMapping
(使用typeof(IClassMapping)
)的Type
对象。在该对象上,调用GetProperty
检索EntityType
属性的PropertyInfo
实例
然后,您应该能够通过调用ValidationDef
实例上的PropertyInfo.GetValue
来检索属性值
例如,使用以下方法:
Type GetEntityType(ValidationDef<T> def)
{
PropertyInfo prop = typeof(IClassMapping).GetProperty("EntityType");
return (Type)prop.GetValue(def, null);
}
Type GetEntityType(ValidationDef)
{
PropertyInfo prop=typeof(IClassMapping).GetProperty(“EntityType”);
返回(类型)prop.GetValue(def,null);
}
好的,澄清之后(请参见问题的注释),下面是在程序集中查找ValidationDef的所有实现并创建其EntityType属性值列表的方法:
List<Type> entityTypes = new List<Type>();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (InheritsFromValidationDef(type))
{
IMappingSource mappingSource = (IMappingSource)Activator.CreateInstance(type);
entityTypes.Add(mappingSource.GetMapping().EntityType);
}
}
private static bool InheritsFromValidationDef(Type type)
{
Type baseType = type.BaseType;
bool result = baseType != null &&
baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == typeof(ValidationDef<>);
return result;
}
List entityTypes=new List();
foreach(在Assembly.getExecutionGassembly().GetTypes()中键入类型)
{
if(继承自验证定义(类型))
{
IMappingSource mappingSource=(IMappingSource)Activator.CreateInstance(类型);
添加(mappingSource.GetMapping().EntityType);
}
}
私有静态bool InheritsFromValidationDef(类型)
{
类型baseType=Type.baseType;
bool result=baseType!=null&&
baseType.IsGenericType&&
baseType.GetGenericTypeDefinition()==typeof(ValidationDef);
返回结果;
}
这里需要注意的几点:
- 正在检查当前程序集中的类型(
)。显然,这对于您的场景来说可能足够,也可能不够assembly.getExecutionGassembly
返回被检查类型的直接父级。同样,您可能希望在继承链的更上层检查类型层次结构BaseType
- 假设所有检查的类型都有一个无参数构造函数。否则,
bit将无法工作Activator.CreateInstance
- 你怎么可能对无法验证的对象调用验证?我认为这是你所有烦恼的根源
- 您的继承层次结构太复杂,难以理解。为什么需要这么多接口
也许可以尝试创建一个单独的问题,详细说明您的验证需求。我相信可以找到一个更简单的解决方案。您可以再详细说明一点吗?
ValidationDef:IValidationDefinition
——保持一致;选择缩写或不缩写。不要同时选择两者。已经阅读并重新阅读您的问题将近10分钟了现在我还是不明白你在问什么。请尝试重新表述它。@KirkWoll。该类实际上来自开源的NHibernate验证器项目,在任何情况下都与此练习无关。我想作者会很乐意听到你的代码审查:——)@Berryl所以在运行时,你希望能够o查找ValidationDef
的所有实现(可能在某些特定程序集中)并创建其EntityType
属性的值列表?对吗?如果为该类型设置了任何类型参数,则BaseType
比较将返回false
。关闭的泛型类型不会从其泛型类型定义继承(可以使用type.GetGenericTypeDefinition
检索)。此外,如果继承关系是间接的,您可能希望使用Type.IsSubclassOf
方法,而不是直接与Type.BaseType
@Nikola Anusev进行相等比较。O.R.Mapper对代码中的错误非常正确;请更正它,以便我可以奖励
List<Type> entityTypes = new List<Type>();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (InheritsFromValidationDef(type))
{
IMappingSource mappingSource = (IMappingSource)Activator.CreateInstance(type);
entityTypes.Add(mappingSource.GetMapping().EntityType);
}
}
private static bool InheritsFromValidationDef(Type type)
{
Type baseType = type.BaseType;
bool result = baseType != null &&
baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == typeof(ValidationDef<>);
return result;
}