Использование задач Reflection и GetValue

У меня есть абстрактный класс, который выглядит так:

public abstract class PageObjectsBase
{
    public abstract string FriendlyName { get; }
    public abstract string PageObjectKeyPrefix { get; }
    public abstract string CollectionProperty { get; }
}

И класс, производный от PageObjectsBase:

public class PageRatingList : PageObjectsBase
{
    public IList<PageRating> PageRatings { get; set; }

    public PageRatingList()
    {
        this.PageRatings = new List<PageRating>();
    }

    public override string CollectionProperty
    {
        get
        {
            var collectionProperty = typeof(PageRatingList).GetProperties().FirstOrDefault(p => p.Name == "PageRatings");
            return (collectionProperty != null) ? collectionProperty.Name : string.Empty;  
        }
    }

    public override string FriendlyName
    {
        get
        {
            return "Page feedback/rating";
        }
    }

    public override string PageObjectKeyPrefix
    {
        get
        {
            return "pagerating-";
        }
    }
}

И класс PageRating, который содержит коллекцию PageRatingList.PageRatings:

public class PageRating : PageObjectBase
{
    public int Score { get; set; }
    public string Comment { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

PageRatingList хранится в базе данных (хранилище динамических данных EPiServer, в частности, с помощью диспетчера объектов страницы). Мне нужно создать некоторые функции отчетности, и я, по сути, загружаю все отчеты, полученные из PageObjectBase. Когда дело доходит до возврата данных, код никогда не узнает во время компиляции, какой тип данных он должен загрузить, поэтому я использую Reflection. В моем классе отчетности у меня есть:

        //this gives me the right type
        var type = Type.GetType("MyNameSpace.PageRatingList", true);

        var startPageData = this._contentRepository.Get<PageData>(startPage);
        PageObjectManager pageObjectManager = new PageObjectManager(startPageData);

        //this loads the instances from the DB
        var props = pageObjectManager.LoadAllMetaObjects()
                         .FirstOrDefault(o => o.StoreName == "Sigma.CitizensAdvice.Web.Business.CustomEntity.PageRatingList");

        //this gives me 4 PropertyInfo objects (IList: PageRatings, string : CollectionProperty, string :FriendlyName, string : PageObjectKeyPrefix)
        var properties = props.Value.GetType().GetProperties();

Затем я могу перебирать объекты PropertyInfo, используя:

        foreach (var property in properties)
        {
            //extract property value here
        }

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как получить значение каждого из объектов propertyinfo. Кроме того, одним из этих свойств является тип List, и снова мы не узнаем тип T до времени выполнения. Поэтому мне также нужна некоторая логика, которая проверяет, относится ли один из объектов PropertyInfo к типу List, а затем предоставляет доступ к каждому из свойств в списке — список имеет тип PageRating.

Кто-нибудь может здесь помочь? Я действительно не использовал отражение в прошлом, поэтому я пробираюсь через него, правильно или неправильно!

Большое спасибо Аль


person higgsy    schedule 23.10.2013    source источник


Ответы (1)


Я могу неправильно понять проблему, но я думаю, что вы можете использовать что-то вроде этого:

   var props = new PageRatingList(); /*actual instanse of the object, in your case, i think "props.Value" */

   var properties = typeof(PageRatingList).GetProperties();

   foreach (var property in properties)
   {
       if (property.PropertyType == typeof(IList<PageRating>))
       {
           IList<PageRating> list  = (IList<PageRating>)property.GetValue(props);

           /* do */
       }
       else
       {
            object val = property.GetValue(props);
       }
    }

Надеюсь, это поможет найти решение.

person Ansenagy    schedule 23.10.2013
comment
Я не уверен в точном смысле публикации ответа, идентичного тому, который я написал, но через полчаса после этого. - person varocarbas; 23.10.2013
comment
Ну... идентичные, идентичные, нет. На самом деле ваш код не компилируется, потому что GetValue всегда принимает как минимум два аргумента (вы даже не тестировали код?). С каждым разом все больше путаюсь в точной точке твоего участия здесь. - person varocarbas; 23.10.2013