我一直在用一些反射代码挣扎,但我会很简单。基本上,我有一个定义方法的接口。然后,我有一个抽象类,它提供了该方法的基本实现。
具体类可以包含其他类的嵌套实例,这些实例也可以派生自相同的基类。可以通过以下示例进行说明:
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的一部分,它以递归方式检查整个层次结构,并返回子项验证问题及其内容。
非常感谢任何帮助。
答案 0 :(得分:2)
怎么样:
var instance = childProperty.GetValue(this, null) as ISampleObject;
if (instance != null)
{
if (!instance.IsValid())
return false;
}
答案 1 :(得分:1)
请查看以下代码是否符合您的要求。我的更改标有以//VH:
public interface ISampleObject
{
bool IsValid();
}
public abstract class SampleObjectBase : ISampleObject
{
public virtual bool IsValid()
{
var returnValue = true; //VH: Changed value from false to true
// Self-validation sets the return value.
var childProperties = this.GetType().GetProperties().Where(pi => typeof(ISampleObject).IsAssignableFrom(pi.PropertyType));
foreach (var childProperty in childProperties)
{
//VH: Here is how you get the value of the property
var childInstance = (ISampleObject)childProperty.GetValue(this, null);
if (childInstance.IsValid() != true)
{
returnValue = false;
}
}
return returnValue;
}
}
public sealed class InnerSampleObject : SampleObjectBase
{
}
public sealed class OuterSampleObject : SampleObjectBase
{
//VH: Added this constructor
public OuterSampleObject()
{
DerivedSampleObject = new InnerSampleObject();
}
public InnerSampleObject DerivedSampleObject { get; set; }
}
class Program
{
static void Main(string[] args)
{
OuterSampleObject c = new OuterSampleObject();
c.IsValid();
}
}
答案 2 :(得分:1)
只需使用
var childInstance = (ISampleObject)childProperty.GetValue(this, null);