2011-05-07 106 views
1

我一直在努力尝试一些反射代码,但我很简单。从本质上讲,我有一个定义方法的接口。然后,我有一个抽象类,提供该方法的基础实现。在不创建新实例的情况下反映嵌套实例

具体类可以包含其他类的嵌套实例,这些类也可以从相同的基类派生。它可以通过下面的示例来说明:

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

看起来你'returnValue'永远不能'真'。 – 2011-05-07 13:27:23

+0

只是一个错字。固定,但。 ;-) – 2011-05-07 13:29:03

回答

2

如何:

var instance = childProperty.GetValue(this, null) as ISampleObject; 
if (instance != null) 
{ 
    if (!instance.IsValid()) 
    return false; 
} 
+0

哦,我的......我以为我曾尝试过,并得到了一个StackOverflowException。我希望我有旧版本,看看我实际上做了什么,但是那个工作很好。 :-) – 2011-05-07 13:49:31

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(); 

    } 
} 
1

只需使用

var childInstance = (ISampleObject)childProperty.GetValue(this, null); 
相关问题