Каковы недостатки использования Reflection для создания команды общего типа в моей модели представления? - PullRequest
3 голосов
/ 12 августа 2011

У меня есть объект данных, который имеет много различных свойств List. Я хочу использовать одну команду AddObject вместо создания разных команд для каждого списка, поэтому придумали следующий код.

Есть ли недостатки, которые вы можете увидеть, используя это? Я думал, что производительность может быть медленной, но я, честно говоря, не видел разницы.

public MyViewModel()
{ 
    _addCommand = new RelayCommand<IEnumerable>(AddGenericObject);

    // Old code.... defines an Add command per list
    // _addAddressCommand = new RelayCommand(() => AddObject<Address>(AddressList));
    // _addPhoneCommand = new RelayCommand(() => AddObject<Phone>(PhoneList));
    // ... etc
}

private void AddGenericObject(IEnumerable list)
{
    // Find Add Method
    var addMethod = this.GetType()
        .GetMethod("AddObject", BindingFlags.NonPublic | BindingFlags.Instance);

    // Created Generic Add Method
    Type genericType = list.GetType().GetGenericArguments()[0];
    var genericAddMethod = addMethod.MakeGenericMethod(genericType);

    // Invoke Method
    genericAddMethod.Invoke(this, new object[] { list });
}

private void AddObject<T>(EntityCollection<T> list)
   where T : EntityObject, new()
{
    var newItem = new T();
    list.Add(newItem);
}

Он используется в XAML чем-то вроде этого:

<Button Content="New Address" 
        Command="{Binding AddCommand}"
        CommandParameter="{Binding AddressList}" />

<Button Content="New Phone" 
        Command="{Binding AddCommand}"
        CommandParameter="{Binding PhoneList}" />

Ответы [ 4 ]

1 голос
/ 12 августа 2011

Производительность всегда является самым важным фактором при рассмотрении вопроса об использовании отражения. В общем, вы должны стараться избегать использования рефлексии, если можете.

1 голос
/ 12 августа 2011

Одним словом - производительность, но перед тем, как избавиться от тестов кода, она может быть достаточно быстрой для ваших нужд.

0 голосов
/ 12 мая 2012

Мой способ сделать это - использовать объект Freezable as Command, передать ему делегат типа Action (of Object) в качестве DependencyProperty и использовать конвертер, который принимает имя метода в качестве ConverterParameter и преобразует ссылку наколлекция в делегат метода Add коллекции (или любого имени метода, которое вы используете в качестве параметра converter) при привязке к коллекции.Таким образом, стоимость отражения возникает только при обмене самим связанным объектом коллекции, что должно быть довольно редко, поскольку вы хотите сохранить ту же коллекцию и просто добавлять и удалять элементы.

Если вы ищетенапример, код, вы можете проверить это сообщение в блоге: http://wpfglue.wordpress.com/2012/05/07/commanding-binding-controls-to-methods/

0 голосов
/ 12 августа 2011

Превосходство - большой фактор, как предположили Джеймс и Дрор.Вы можете сделать следующее для кэширования метода.

    private MethodInfo cachedMethod = null;
    private void AddGenericObject(IEnumerable list)
    {
        if (cachedMethod == null)
        {
            // Find Add Method
            var addMethod = this.GetType()
                 .GetMethod("AddObject", BindingFlags.NonPublic | BindingFlags.Instance);

            // Created Generic Add Method
            var genericType = list.GetType().GetGenericArguments()[0];
            cachedMethod = addMethod.MakeGenericMethod(genericType);
        }

        // Invoke Method
        cachedMethod.Invoke(this, new object[] { list });
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...