我正在尝试为.NET 4中的POCO对象创建一个基类,它将具有Include(字符串路径)方法,其中path是“。”要枚举的继承类的嵌套ICollection属性的分隔导航路径。
例如,给定以下类别;
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
}
}
}
}
}
显然,“var list = ...&gt;” line不起作用,但你希望获得要点,除非propertyCollection是可枚举的,否则foreach将无法工作。
所以这是最后一点,即如果直到运行时我不知道T的类型,我该如何枚举类的ICollection属性?
由于
答案 0 :(得分:1)
你不需要反思。为了枚举它,您只需要一个IEnumerable
。 ICollection<T>
继承IEnumerable
,因此您的所有收藏都将是枚举。因此,
var propertyCollection = (IEnumerable) propertyValue;
foreach (object item in propertyCollection)
// ...
会奏效。
答案 1 :(得分:0)
当客户端可以在 compile -time解析泛型类型时,通常会使用泛型。
暂且不说,因为您需要做的只是枚举propertyCollection
(将序列的每个元素简单地视为System.Object
),您需要做的就是:
var propertyCollection = (IEnumerable)propertyValue;
foreach(object item in propertyCollection)
{
...
}
这是非常安全的,因为ICollection<T>
扩展了IEnumerable<T>
,而IEnumerable
又延伸了T
。 object
实际上最终在运行时的结果是无关紧要的,因为循环只需要System.Object
。
真正的问题是:{{1}}在循环中是否足以满足您的目的?