2010-09-20 3 views
1

Я пытаюсь создать базовый класс для своих объектов POCO в .NET 4, который будет иметь метод Include (string path), где path является «.». ограниченный путь навигации вложенных свойств ICollection наследующего класса, подлежащего перечислению.Enumerate 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 
       } 
      } 
     } 
    } 
} 

Очевидно, что «список вара = ...>» линия не работает, но вы, надеюсь, получите суть, и Еогеасп не будет работать, если не является propertyCollection перечисляемости.

Итак, это последний бит, то есть как я могу перечислить свойство ICollection класса, когда я не знаю тип T до времени выполнения?

Благодаря

ответ

1

Для этого не требуется отражение. Чтобы перечислить его, вам понадобится только IEnumerable. ICollection<T> наследует IEnumerable, поэтому все ваши коллекции будут перечисляемыми. Поэтому

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

будет работать.

+0

Да, это так! Благодарю. :-) – Phil

0

Дженерики, как правило, используется, когда клиент может разрешить общий тип в компиляции -time. Оставляя это в стороне, так как все, что вам нужно сделать, это перечислить propertyCollection (просмотр каждого элемента последовательности просто как System.Object) все, что вам нужно сделать, это:

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

Это совершенно безопасно, так как ICollection<T> расширяет IEnumerable<T>, который, в свою очередь, распространяется на IEnumerable. То, что T на самом деле заканчивается во время выполнения, не имеет значения, поскольку для цикла требуется только object.

Реальный вопрос: есть ли System.Object, достаточный для ваших целей внутри цикла?

+0

К счастью, достаточно лить объект как объект, так как я все еще могу вызвать метод Include через GetMethod. – Phil

Смежные вопросы