Добавление элемента в общий список <T>с отражением - PullRequest
1 голос
/ 15 апреля 2011

Редактировать: Идите, пожалуйста, здесь ничего не видно.

Решение этого вопроса не имело ничего общего с Reflection, и все, что было связано со мной, не обращало внимания на реализацию свойства collection в базовом классе.


Я пытаюсь добавить элемент в коллекцию, используя Reflection, используя следующий метод:

public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
    Type targetResourceType = targetResource.GetType();
    PropertyInfo collectionPropertyInfo = targetResourceType.GetProperty(propertyName);

    // This seems to get a copy of the collection property and not a reference to the actual property
    object collectionPropertyObject = collectionPropertyInfo.GetValue(targetResource, null);
    Type collectionPropertyType = collectionPropertyObject.GetType();
    MethodInfo addMethod = collectionPropertyType.GetMethod("Add");

    if (addMethod != null)
    {
        // The following works correctly (there is now one more item in the collection), but collectionPropertyObject.Count != targetResource.propertyName.Count
        collectionPropertyType.InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, collectionPropertyObject, new[] { resourceToBeAdded });
    }
    else
    {
        throw new NotImplementedException(propertyName + " has no 'Add' method");
    }
}

Однако, похоже, что вызов targetResource.GetType().GetProperty(propertyName).GetValue(targetResource, null) возвращает копию targetResource.propertyName, а не ссылку на нее, и поэтому последующий вызов collectionPropertyType.InvokeMember влияет на копию, а не на ссылку.

Как добавить объект resourceToBeAdded в свойство коллекции propertyName объекта targetResource?

1 Ответ

4 голосов
/ 15 апреля 2011

Попробуйте это:

public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
    var col = targetResource.GetType().GetProperty(propertyName).GetValue(targetResource, null) as IList;
    if(col != null)
        col.Add(resourceToBeAdded);
    else
        throw new InvalidOperationException("Not a list");
}

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

void Main()
{

    var t = new Test();
    t.Items.Count.Dump(); //Gives 1
    AddReferenceToCollection(t, "Items", "testItem");
    t.Items.Count.Dump(); //Gives 2
}
public class Test
{
    public IList<string> Items { get; set; }

    public Test()
    {
        Items = new List<string>();
        Items.Add("ITem");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...