Как получить доступ к свойству для каждого элемента индексатора, используя отражение в C # .net 2.0 - PullRequest
0 голосов
/ 21 октября 2009

У меня есть следующий метод:

object GetIndexer()

Результатом метода является индексатор типа:

SomeCollection<T>

Теперь T может быть чем угодно, я знаю, что каждый T расширяет тип Y.

Я попробовал кастинг

SomeCollection<Y> result= (SomeCollection<Y>) GetIndexer()

Это не сработало.

Что мне нужно знать, так это как получить доступ к свойству для каждого элемента в индексаторе SomeCollection с помощью Reflection?

Ответы [ 4 ]

2 голосов
/ 21 октября 2009

Используйте GetType() для каждого элемента, затем вызовите либо GetProperties () или GetProperty (propertyName) , чтобы получить PropertyInfo. После этого вы вызываете GetValue(), передавая ваш объект.

Пример:

    List<object> objects = new List<object>();
    // Fill the list
    foreach (object obj in objects)
    {
        Type t = obj.GetType();
        PropertyInfo property = t.GetProperty("Foo");
        property.SetValue(obj, "FooFoo", null);
        Console.WriteLine(property.GetValue(obj, null));            
    }
0 голосов
/ 21 октября 2009

Цикл по списку - это процесс перечисления. Проще всего с перечислителем. То есть (в C #): все, что реализует IEnumberable.

Если объект, который вы пытаетесь зациклить, принадлежит вам самому, я рекомендую реализовать IEnumberable. Если нет, можете ли вы дать больше информации об этом конкретном стороннем объекте? Возможно, есть другие, которым также нужно было использовать его таким образом, и, возможно, один из нас может найти его работу в Интернете.

0 голосов
/ 21 октября 2009

Является ли SomeCollection<T> перечислимым? Если это так, вы могли бы сделать

 var transformed = new SomeCollection<Y>();

 var someObjectCollection = (IEnumberable)GetIndexer();
 foreach (var someObjectin someObjectCollection);
     transformed.Add((Y)someObject);

Или подождите, пока C # 4.0 даст нам больше вариантов ковариации и контравариантности.

0 голосов
/ 21 октября 2009

Некоторый контекст был бы полезен, но похоже, что у вас есть что-то вроде

class Foo<T> where T : Y {
    object GetIndexer() { /* ... */ }
}

В таком случае, почему бы просто

    SomeCollection<Y> GetIndexer() { /* */ }

Таким образом, не требуется каст.

Но меня немного смущает использование вами термина «индексатор». Индексатор для C # - это способ перегрузки оператора [] для типа, так что вы можете делать такие вещи, как:

MyCollectionType c = new MyCollectionType()
c["someValue"]

Они определены так:

class MyCollectionType {
    public string this [string index] // This particular indexer maps strings to strings, but we could use other types if we wished.
    get {} // Defines what to do when people do myCollection["foo"]
    set {} // Defines what to do when people do myCollection["foo"] = "bar"
}

Объект типа SomeCollection<Y> не является индексатором, это коллекция.

...