Комментарии 21
Если вы понимаете «разницу» между (1), (2), (3), то итоговая разница во времени случайна. (6) https://habrahabr.ru/post/281294/#comment_8847910
+7
> Использование аоп тормознет приложение на прочь
Там проблема не в АОП. Это АОП курильщика.
Возьмите Fody/PropertyChanged, KindOfMagic.
Там проблема не в АОП. Это АОП курильщика.
Возьмите Fody/PropertyChanged, KindOfMagic.
+2
Есть еще такой проект — AspectInjector разрабатыемый нами. В гитхабе как раз есть пример с INotifyPropertyChanged
0
Некоторое время назад хотел добавить немного АОП в свой код, но не устраивала постобработка скомпиленного кода и совместимость с текущим пайплайном. В результате для этого делал свой велосипед.
Попробовал локально ваш тест прогнать, различия в районе 10% от 1-го решения. Мне кажется это более верная реализация АОП, если не хочется статического.
Если захочется проверить, то в вся документация в тестах. Но что бы не копаться можно использовать такую реализацию:
Попробовал локально ваш тест прогнать, различия в районе 10% от 1-го решения. Мне кажется это более верная реализация АОП, если не хочется статического.
Если захочется проверить, то в вся документация в тестах. Но что бы не копаться можно использовать такую реализацию:
public class TestModel : NotificationObject, IData
{
[NotifyProperty]
public virtual int Value { get; set; }
public TestModel()
{
Notificator.Create(this);
}
}
0
Тяжело читать из-за колоссального количества орфографических и пунктуационных ошибок в тексте.
+1
Ещё хотелось бы посмотреть код, с помощью которого получились данные результаты.
0
Выложу, чуть позже.
0
Обещанного три года ждут…
но мы ж не улитки
вот код программы
интерфейс улиток (эх название у интерфейса подкачало)
пример реализации
особо опасная реализация
запустил тест на другом компьютере, и вот результат
разница не велика
но мы ж не улитки
вот код программы
class Program
{
[STAThread]
static void Main( string[] args )
{
IUnityContainer container = new UnityContainer();
container.RegisterViewModel<DataAop>();
var dataAop = container.Resolve<DataAop>();
List<IData> listOfData = new List<IData>();
listOfData.Add( dataAop );
var asm = System.Reflection.Assembly.GetExecutingAssembly();
var excludes = new HashSet<Type> { typeof( IData ), typeof( DataAop ), typeof( ProxyData ), typeof( DataObservableObject ) };
listOfData.AddRange( asm.GetTypes()
.Where( t => typeof( IData ).IsAssignableFrom( t ) && !excludes.Contains( t ) ).Select( t => Activator.CreateInstance( t ) as IData ) );
foreach (var notify in listOfData.Cast<INotifyPropertyChanged>())
notify.PropertyChanged += OnPropertyChanged;
DataObservableObject observableData = new DataObservableObject();
var propDesp = DependencyPropertyDescriptor.FromProperty( ObservableObject<int>.ValueProperty, typeof( ObservableObject<int> ) );
propDesp.AddValueChanged( observableData.RealValue, OnPropertyChanged );
listOfData.Add( observableData );
Console.WriteLine( string.Format( "Start ---> {0}", DateTime.Now ) );
Stopwatch sw = new Stopwatch();
foreach (var data in listOfData)
{
sw.Restart();
for (int i = 0; i < 10000000; i++)
data.Value = i;
sw.Stop();
Console.WriteLine();
Console.WriteLine( string.Format( "Iteration date {0}, data name {1}, elapsed {2}",
DateTime.Now, data.GetType().Name, sw.ElapsedMilliseconds ) );
}
Console.WriteLine( string.Format( "Stop ---> {0}", DateTime.Now ) );
Console.ReadKey();
}
static void OnPropertyChanged( object sender, EventArgs e ) { }
static void OnPropertyChanged( object sender, PropertyChangedEventArgs e ) { }
}
интерфейс улиток (эх название у интерфейса подкачало)
public interface IData
{
int Value { get; set; }
}
пример реализации
class DataString : BindableBase, IData
{
int _value;
public int Value
{
get
{
return _value;
}
set
{
if (_value != value)
{
_value = value;
OnPropertyChanged("Value");
}
}
}
}
особо опасная реализация
class DataObservableObject : IData
{
public DataObservableObject()
{
RealValue = new ObservableObject<int>();
}
public ObservableObject<int> RealValue { get; private set; }
public int Value
{
get
{
return RealValue.Value;
}
set
{
RealValue.Value = value;
}
}
}
запустил тест на другом компьютере, и вот результат
разница не велика
0
Что такое [CallerMemberName]? Как происходит определение имени текущего свойства?
0
От куда вы все знаете?
Вот как вы пришли к этим знаниям?
И какие интерфейсы стоит изучать в первую очередь(.NET)?
Вот как вы пришли к этим знаниям?
И какие интерфейсы стоит изучать в первую очередь(.NET)?
0
Методы 1, 2 и 3 генерируют одинаковый IL код, разница лишь в предпочтении автора. 1-й может привести к ошибке, в случае переименования свойства,. 2-й метод в этом плане удобнее, т.к. инструмент вроде ReSharper автоматически переименует и свойство, и конструкцию nameof(Property). 5-й метод может быть удобен для реализации дополнительной логики: логирование, сравнение значений и генерация события лишь на действительном изменении значения, генерация события PropertyChanging а потом PropertyChanged. 4,6,7 не вижу смысла, да и вообще велосипеды облегчения реализации INotifyPropertyChanged не читаю, будто других проблем в WPF нет, как сэкономить 1 строку кода на 1-м свойстве. «Дабпиэф ничего не поделаешь» при отрисовке списка говорят, наверное, только джуны, никогда не читавшие исходников VirtualizingStackPanel и ItemsControl и не писавших свои панели, реализующие виртуализацию отображения, там в принципе нечему тормозить.
0
В целом поддерживаю, за исключением четвертой улитки, хорошая альтернатива nameof в условиях отсутствия c# 6 версии. Ну и про тормознутый список говорил не юниор, а разработчик которому было искрнни лень исправлять проблемный код
0
«Дабпиэф ничего не поделаешь» при отрисовке списка говорят, наверное, только джуны, никогда не читавшие исходников VirtualizingStackPanel
Это там, где по 20 реф-параметров передается? Ну действительно, тормозить совершенно нечему. Или по 3 цикла отрисовки на каждый элемент? Тоже норм.
Методы 1, 2 и 3 генерируют одинаковый IL код, разница лишь в предпочтении автора. 1-й может привести к ошибке, в случае переименования свойства,. 2-й метод в этом плане удобнее, т.к. инструмент вроде ReSharper автоматически переименует и свойство, и конструкцию nameof(Property).
Как раз-таки только решарпер переименует в первом случае и свойство, и имя, а вот студия внесет изменения только при явном использовании переменной в nameof.
0
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Миллион и один день INotifyPropertyChanged