【发布时间】:2011-05-07 13:01:05
【问题描述】:
我一直在为一些我认为很简单的反射代码而苦苦挣扎。本质上,我有一个定义方法的接口。然后,我有一个提供该方法的基本实现的抽象类。
具体类可以包含其他类的嵌套实例,这些实例也可以派生自同一个基类。可以用下面的例子来说明:
using System.Linq;
public interface ISampleObject
{
bool IsValid();
}
public abstract class SampleObjectBase : ISampleObject
{
public bool IsValid()
{
var returnValue = true;
// Self-validation sets the return value.
var childProperties = this.GetType().GetProperties().Where(pi => typeof(ISampleObject).IsAssignableFrom(pi.PropertyType));
foreach (var childProperty in childProperties)
{
// var childInstance = ????; // Need the actual *existing* instance property, cast to ISampleObject.
// if (childInstance.IsValid() != true)
// {
// returnValue = false;
// }
}
return returnValue;
}
}
public sealed class InnerSampleObject : SampleObjectBase
{
}
public sealed class OuterSampleObject : SampleObjectBase
{
public InnerSampleObject DerivedSampleObject { get; set; }
}
我的问题是,在 SampleObjectBase 的注释代码中,我无法获得匹配的 PropertyInfo 值的具体实例。如果我查看循环中的 PropertyInfo 对象,我发现类型是正确的,但是我找不到直接访问实现中已经存在的实例的方法。因此,例如,在执行 OuterSampleObject.IsValid() 时,代码会按预期找到 InnerSampleObject 的 PropertyInfo。我想执行 InnerSampleObject.IsValid()。
我已经尝试过(多种变体):
var childIsValid = (bool)contractProperty.PropertyType.InvokeMember("IsValid", BindingFlags.InvokeMethod, null, null, null);
还有:
var childInstance = (ISampleContract)contractProperty;
第一个问题是我不能将 null 作为 InvokeMember 的目标传递,因为 IsValid() 不是静态的(也不能是,因为我专注于实际实例)。第二个只是一个蹩脚的演员,但却是我想要完成的事情的要点。
上面的示例代码只是我想要实现的极简示例。完整代码是自验证 DTO 的一部分,它递归地检查整个层次结构并返回哪些子级存在验证问题以及它们是什么。
任何帮助将不胜感激。
【问题讨论】:
-
看起来你的
returnValue永远不可能是true。 -
只是一个错字。不过,已修复。 ;-)
标签: c# reflection system.reflection