2010-09-20 61 views
1

我想在.NET 4中为我的POCO对象创建一个基类,它将有一个Include(字符串路径)方法,其中路径是“。”。要枚举的继承类的嵌套ICollection属性的分隔导航路径。枚举ICollection <T>使用Reflection的类的属性

例如,给定以下类别;

public class Region 
{ 
    public string Name { get; set; } 
    public ICollection<Country> Countries { get; set; } 
} 
public partial class Region : EntityBase<Region> {} 

public class Country 
{ 
    public string Name { get; set; } 
    public ICollection<City> Cities { get; set; } 
} 
public partial class Country : EntityBase<Country> {} 

public class City 
{ 
    public string Name { get; set; } 
} 
public partial class City : EntityBase<City> {} 

我希望能够做到这样的事情;

Region region = DAL.GetRegion(4); 
region.Include("Countries.Cities"); 

到目前为止,我有以下;

public class EntityBase<T> where T : class 
{ 
    public void Include(string path) 
    { 
     // various validation has been omitted for brevity 
     string[] paths = path.Split('.'); 
     int pathLength = paths.Length; 
     PropertyInfo propertyInfo = type(T).GetProperty(paths[0]); 
     object propertyValue = propertyInfo.GetValue(this, null); 
     if (propertyValue != null) 
     { 
      Type interfaceType = propertyInfo.PropertyType; 
      Type entityType = interfaceType.GetGenericArguments()[0]; 

      // I want to do something like.... 
      var propertyCollection = (ICollection<entityType>)propertyValue; 
      foreach(object item in propertyCollection) 
      { 
       if (pathLength > 1) 
       { 
        // call Include method of item for nested path 
       } 
      } 
     } 
    } 
} 

显然,“无功名单= ...>”行不工作,但你希望得到的要点,并在foreach不会工作,除非是propertyCollection枚举。

所以这是最后一点,即当我直到运行时才知道T的类型时,如何枚举类的ICollection属性?

感谢

回答

1

你不需要反思。为了枚举它,你只需要一个IEnumerableICollection<T>继承IEnumerable,所以你的所有集合都是枚举类型。因此,

var propertyCollection = (IEnumerable) propertyValue; 
foreach (object item in propertyCollection) 
    // ... 

将工作。

+0

是的,它的确如此!我的谢意。 :-) – Phil 2010-09-20 13:21:56

0

泛型正常使用时,客户端可以解决一般类型的编译 - 时间。 离开那一边,因为所有你需要做的是propertyCollection枚举(序列的观察每个元素仅仅作为一个System.Object)所有你需要做的是:

var propertyCollection = (IEnumerable)propertyValue; 
foreach(object item in propertyCollection) 
{ 
    ... 
}  

这是完全安全的,因为ICollection<T>延伸IEnumerable<T>,而这又延伸IEnumerableT实际上在运行时最终会变得无关紧要,因为循环只需要object

真正的问题是:System.Object足以满足您在循环内的目的吗?

+0

幸运的是,只需将对象转换为对象,因为我仍然可以通过GetMethod调用Include方法。 – Phil 2010-09-20 13:26:11