CreateDelegate о методе расширения - PullRequest
0 голосов
/ 13 мая 2011

У меня есть класс со свойством IList только для чтения. Я создал простой метод расширения AddCSV, чтобы добавить несколько элементов в этот список. Я хочу создать делегат действия для заполнения списка с помощью метода расширения. Пока у меня есть

private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
{
    var list = typeof(TListPropertyContainer).GetProperty(listName);
    var method = typeof(Extensions).GetMethod("AddCSV");
    return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}

но, очевидно, это не работает!

Я в курсе, что есть и другие варианты. Например а) я мог бы унаследовать список в своем собственном классе клиента и добавить туда AddCSV б) я могу сделать свойство items доступным для чтения / записи и установить полностью заполненный список в свой класс

Буду благодарен, если кто-нибудь сможет меня поправить.

Многие, спасибо

Simon

Ответы [ 2 ]

2 голосов
/ 13 мая 2011

Есть две основные проблемы.

  1. Вы пытаетесь вызвать метод для PropertyInfo, а не для списка.Чтобы получить значение свойства, вам нужно вызвать GetValue()

  2. В вызове GetMethod() не указаны флаги привязки.Я подозреваю, что это может работать лучше с GetMethod("AddCSV", BindingFlags.Public | BindingFlags.Static).

При этом, почему вы задумываетесь об этом, когда заранее знаете тип и метод?Кажется, что вы могли бы просто сделать:

 private Action<TListPropertyContainer, TDataValue> CreateListPropertySetter<TListPropertyContainer, TDataValue>(string listName)
 {
       var propertyInfo = typeof(TListPropertyContainer).GetProperty(listName);
       return (container,value) => {
            var list = (IList<TDataValue>)propertyInfo.GetValue(container,null);
            list.AddCSV(list);
       };
  }

Если я делаю неверные предположения о сигнатуре метода расширения или типе свойства, вы все равно можете сделать это с помощью Delegate.CreateDelegate(), но примите комментариио PropertyInfo и BindingFlags на счет

1 голос
/ 13 мая 2011

Вы пытаетесь использовать list в качестве цели делегата, но list имеет тип PropertyInfo, что выглядит как не , что вы ожидали.Предполагая, что вы хотите получить значение свойства, а затем вызвать метод для этого, вам также нужно будет передать объект, содержащий свойство, чтобы вы могли получить фактический список.(В качестве альтернативы, может быть, это «это» - вы на самом деле не сделали этого ясно.) В любом случае, вы можете получить сам список и использовать , что в качестве цели.Например:

private Action<TListPropertyContainer, TDataValue> 
    CreateListPropertySetter<TListPropertyContainer, TDataValue>
    (string listName, object target)
{
    var listProperty = typeof(TListPropertyContainer).GetProperty(listName);
    object list = listProperty.GetValue(target, null);
    var method = typeof(Extensions).GetMethod("AddCSV");
    return (Action<TListPropertyContainer, TDataValue>)Delegate.CreateDelegate(
        typeof(Action<TListPropertyContainer, TDataValue>), list, method);
}

Если это не поможет, отредактируйте ваш вопрос с помощью короткого, но завершенного консольного приложения, демонстрирующего проблему.Прямо сейчас есть слишком много неизвестных, чтобы определенно помочь вам.

...