Добрый день, господа.
Хочу поделится классом, который я использую для типобезопасного взятия имени свойства.
Для чего это нужно.
Основные области пременеия это выстрел события INotifyPropertyChanged.PropertyChanged и автоматические тесты.
Чем лучше строковых переменных?
Первое, но не главное — не ошибиться в написании имени свойства.
Второе и главное, при изменении имени свойства с помощью автоматического рефакторинга, не надо заботиться об соответствующем изменении строковых переменных.
Чем хуже.
Производительность не высокая, не стоит использовать там, где будут тысячи запросов имени свойства в секунду.
Есть два способа взять имя свойства
1. Когда есть только тип, имя свойства которого надо взять.
nameof<Type>.Property( x => x.Property );
2. Когда есть переменная нужного типа.
nameof.Property( () => variable.Property );
Примеры использования:
INotifyPropertyChanged — второй способ, есть переменная this.
class Presenter : INotifyPropertyChanged
{
private int _megaProperty;
public int MegaProperty
{
get { return _megaProperty; }
set
{
_megaProperty = value;
RaisePropertyChanged( nameof.Property(() => MegaProperty) );
}
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
В тестах (приведены тесты nunit) используются оба
1.
Assert.That(presenter.Items, Is.All.Property( nameof<NodeType>.Property(x => x.Name) ).StartsWith("123"));
Assert.That(nodes, Is.Ordered.By( nameof<NodeType>.Property(n => n.Name) ));
2.
eventExpectator.AssertWasCalled(h => h.Invoke(Arg<object>.Is.Anything, Arg<PropertyChangedEventArgs>.Matches(args =>
args.PropertyName == nameof.Property(() => presenter.Items))), null);
Собственно код классов
public static class nameof
{
public static string Property< TV >( Expression< Func< TV > > property )
{
var body = property.Body as MemberExpression;
if(body == null)
throw new ArgumentException("'expression' should be a member expression");
return body.Member.Name;
}
}
public static class nameof< T >
{
public static string Property< TV >( Expression< Func< T, TV > > property )
{
var body = property.Body as MemberExpression;
if(body == null)
throw new ArgumentException("'expression' should be a member expression");
return body.Member.Name;
}
}
надеюсь кому-нибудь пригодится
Ed.ward
31.05.11 11:30: Перенесено из '.NET'