powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Универсальный setter
25 сообщений из 65, страница 2 из 3
Универсальный setter
    #38531689
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да.
...
Рейтинг: 0 / 0
Универсальный setter
    #38531690
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileuser7320а зачем дебажить? Всё же на юнит-тестах делается. Тупо меняешь код, пока тесты не начнут проходить. Дебажить даже не надо.
У тебя какое-то наивное представление о процессе разработки. Даже если код на 100% покрыт юнит-тестами, то все равно без отладки не получится обойтись. Не говорят уже о том что 100% покрытие встречается не так часто.
А сами тесты надо дебажить?
...
Рейтинг: 0 / 0
Универсальный setter
    #38531691
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.
...
Рейтинг: 0 / 0
Универсальный setter
    #38531692
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей К,

ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да.Ну я и предложил с оговоркой, что если производительность позволяет. А она скорее всего позволяет, это же отображение данных, их при отображении обычно много не бывает.
...
Рейтинг: 0 / 0
Универсальный setter
    #38531697
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Алексей К,

а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.Если честно, первый раз его вижу. Тут надо подумать. :-)
...
Рейтинг: 0 / 0
Универсальный setter
    #38531700
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Алексей К,

а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.Оно под 4.5, а мне под 4.0 надо. :-(
...
Рейтинг: 0 / 0
Универсальный setter
    #38531704
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КnetivanАлексей К,

ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да.Ну я и предложил с оговоркой, что если производительность позволяет. А она скорее всего позволяет, это же отображение данных, их при отображении обычно много не бывает.
ну понятно, хотя вдруг обновление грида 1 млн в секунду, вот там будет заметно. Да и вообще можно и string передавать, ничего криминального не вижу тут.Раздули из такой фигни целую тему)
...
Рейтинг: 0 / 0
Универсальный setter
    #38531718
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanну понятно, хотя вдруг обновление грида 1 млн в секунду, вот там будет заметно.Уверен, там тонкое место будет в другом месте. :-)
netivanДа и вообще можно и string передавать, ничего криминального не вижу тут.Если будет ошибка в имени свойства - её будет непросто отловить. С Expression как-то спокойнее. :-)
netivanРаздули из такой фигни целую тему)Я узнал про CallerMemberName, значит не зря. :-)
...
Рейтинг: 0 / 0
Универсальный setter
    #38531941
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Алексей К,

а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.
Вряд ли в разы - это решение решает только проблему вызова PropertyChanged, backing fields и логика оповещения зависимостей будет всё так же присутствовать. Решение по ссылке, которую я постил на предыдущей странице, действительно ощутимо сжимает код (базовый класс модели получился достаточно объемным). Единственное "но" этого решения - строчные именования свойств в атрибуте описания зависимости, но это решается рантаймовой проверко в конструкторе.
...
Рейтинг: 0 / 0
Универсальный setter
    #38532090
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileчто нужно тестировать, а что нет.
Ну это вообще я поприкалывался раз - на заседации.
Купили "Ковертюру" - это для джавы такая утилита, которая как раз замеряет покрытие юнит-тестами.
(этож еще деньги на этом зарабатывают!!! )

И она дает 25%. Полно кода, где юнит тестить просто нечего. То есть, абсолютно.
А обсуждался вопрос, как пометить едиообразно те методы, которая Кю вертюра брать в рассчет не должна.

А я им рассказал случай, из геологической практики моих родителей -
Когда некий руководитель получил от буровиков соц. обязательства - обеспечить выход керна 78%.
Начал возмущаться - как это 78%!!! Вся страна берет повышенные обязательства - 106% , даже 110%!!! А вы только 78!!!!
Не менее 103 должно быть!

Я им и сказал - что не надо насиловать инструмент, то, что данный тип аппликации покрыт на 25% - это научный факт.
Норма. Изменится тип проэкта - изменится и цифра. Незачем вносить в код то, что не код.

:-)))
...
Рейтинг: 0 / 0
Универсальный setter
    #38532110
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129bazileчто нужно тестировать, а что нет.
Ну это вообще я поприкалывался раз - на заседации.
Купили "Ковертюру" - это для джавы такая утилита, которая как раз замеряет покрытие юнит-тестами.
(этож еще деньги на этом зарабатывают!!! )

И она дает 25%. Полно кода, где юнит тестить просто нечего. То есть, абсолютно.
А обсуждался вопрос, как пометить едиообразно те методы, которая Кю вертюра брать в рассчет не должна.

А я им рассказал случай, из геологической практики моих родителей -
Когда некий руководитель получил от буровиков соц. обязательства - обеспечить выход керна 78%.
Начал возмущаться - как это 78%!!! Вся страна берет повышенные обязательства - 106% , даже 110%!!! А вы только 78!!!!
Не менее 103 должно быть!

Я им и сказал - что не надо насиловать инструмент, то, что данный тип аппликации покрыт на 25% - это научный факт.
Норма. Изменится тип проэкта - изменится и цифра. Незачем вносить в код то, что не код.

:-)))
Ваши проблемы от того, что у ваших заказчиков до... денег. Вот и беситесь с жиру, выкидываете бабки на всякие утилиты, и без которых ясно, что к чему... С другой стороны, всяким кувертюрам тоже жить надо - у них свои семьи, дети.
...
Рейтинг: 0 / 0
Универсальный setter
    #38532137
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320всяким кувертюрам тоже жить надо - у них свои семьи, дети.
Вопрос только в том, когда падет Рим.
:-)
...
Рейтинг: 0 / 0
Универсальный setter
    #38535598
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Дело опять касается boilerplate реализаций INotifyPropertyChanged и свойств.

Как вам такое решение (нашёл в Интернете)? Какие плюсы и минусы вы видите? Есть вообще смысл так делать - "униваресальные свойства" и т. п.?

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


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
public class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            OnPropertyChanged(propertyName);
        }
    }
}


// Использование.

public MyClass : Base
{
    private string _myField;
    public string MyProperty
    {
        get { return _myField; }
        set { this.SetProperty<string>(ref _myField, value); }
    }
}


Ну вот и первый камушек...

Значит, в MVVM, если мы используем модель как поле, хранящее значение свойств модели представления (т. е. в самой модели представления отдельных полей для хранения значений свойств нет), то так, как я выше написал в сеттере, сделать нельзя.

Т. е. если имеем

Код: c#
1.
2.
3.
4.
class Model
{
    public int A { get; set; }
}



То вот так сделать нельзя

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class ViewModel
{
    Model _model;
    
    public int A
    {
        get { return _model.A; }
        set { SetProperty(ref _model.A, value); }
    }
}



Т. к. получим исключение "A property, indexer or dynamic member access may not be passed as an out or ref parameter".

А получится сделать вот так

Код: c#
1.
2.
3.
4.
5.
6.
        set
        {
            var a = _model.A;
            SetProperty(ref a, value);
            _model.A = a;
        }



Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало?
...
Рейтинг: 0 / 0
Универсальный setter
    #38535632
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
public int A
{
    set { SetProperty(v => _model.A = v, value); }
}
...
Рейтинг: 0 / 0
Универсальный setter
    #38535642
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320
Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало?

Код: c#
1.
2.
3.
4.
5.
6.
7.
SetProperty (string proprtyName)
{
    if (OnPropertyCanged != null)
    {
         OnPropertyCanged (new ProprtyChangedEvenArgument(proprtyName));
    }
}



:-))))))))))))
...
Рейтинг: 0 / 0
Универсальный setter
    #38535645
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129user7320Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало?

Код: c#
1.
2.
3.
4.
5.
6.
7.
SetProperty (string proprtyName)
{
    if (OnPropertyCanged != null)
    {
         OnPropertyCanged (new ProprtyChangedEvenArgument(proprtyName));
    }
}



:-))))))))))))Нет! В этом случае с программой разберётся любой посторонний. Нам это не надо! :-)
...
Рейтинг: 0 / 0
Универсальный setter
    #38535791
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129user7320Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало?

Код: c#
1.
2.
3.
4.
5.
6.
7.
SetProperty (string proprtyName)
{
    if (OnPropertyCanged != null)
    {
         OnPropertyCanged (new ProprtyChangedEvenArgument(proprtyName));
    }
}



:-))))))))))))
А где тут присвоение значения?

Алексей К
Код: c#
1.
2.
3.
4.
public int A
{
    set { SetProperty(v => _model.A = v, value); }
}


А выполнение? Что-то типа такого?

Код: c#
1.
2.
3.
4.
5.
protected void SetProperty<T>(Expression<Action<T>> e, T value, [CallerMemberName] string propertyName = "")
{
    var action = e.Compile();
    action.Invoke(value);
}



А как такую проверку сделать?

Код: c#
1.
2.
3.
4.
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
            }



Не пойму, как вытащить field из тела выражения.
...
Рейтинг: 0 / 0
Универсальный setter
    #38535796
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е., там можно даже без выражения - сразу делегат. Но всё равно не понятно, как сделать проверку старого и нового значения поля. Разве что ещё один параметр ввести - старое значение поля - и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять?
...
Рейтинг: 0 / 0
Универсальный setter
    #38535808
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320У тебя от экспешенов уже крыша поехала. :-)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
protected void SetProperty<T>(Func<T> getter, Action<T> setter, T newValue, [CallerMemberName] string propertyName = "")
{
    var oldValue = getter();

    if (!EqualityComparer<T>.Default.Equals(oldValue, newValue))
    {
        setter(newValue);
        OnPropertyChanged(propertyName);
    }
}
...
Рейтинг: 0 / 0
Универсальный setter
    #38535812
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 public ReceiptLine SelectedReceiptLine
        {
            get { return _selectedGiftReceiptLine; }
            set
            {
                if (_selectedReceiptLine == value) return;
                _selectedReceiptLine = value;
                NotifyPropertyChanged("SelectedReceiptLine");
            }
        }



И вот реализация (!!!) NotifyPropertyChanged:

Код: c#
1.
2.
3.
4.
5.
6.
7.
 protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }



Транспортное средство двухколесное изобретать будем?
:-)
...
Рейтинг: 0 / 0
Универсальный setter
    #38535825
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Напиши уже T4 Template какой-нибудь или кодогенератор для XML. Там работы на 20 минут.
...
Рейтинг: 0 / 0
Универсальный setter
    #38535839
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или вообще вот так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
class MyEntity
{
    public virtual int Value { get; set; }
}

// Там внутри через Emit замутить потомка указанного класса, перекрыть виртуальное
// свойство и сгенерировать в него что хочешь.
var obj = NotificationFactory.Create<MyEntity>();


Тут пример реализации.
...
Рейтинг: 0 / 0
Универсальный setter
    #38535845
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если надо работать с инкапсулированной моделью оно будет выглядеть так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
class MyViewModel
{
   public virtual int Value 
   { 
       get { return _model; } 
       set { _model.Value = value; }
   }
}
...
Рейтинг: 0 / 0
Универсальный setter
    #38535850
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129user7320и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 public ReceiptLine SelectedReceiptLine
        {
            get { return _selectedGiftReceiptLine; }
            set
            {
                if (_selectedReceiptLine == value) return;
                _selectedReceiptLine = value;
                NotifyPropertyChanged("SelectedReceiptLine");
            }
        }



И вот реализация (!!!) NotifyPropertyChanged:

Код: c#
1.
2.
3.
4.
5.
6.
7.
 protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }



Транспортное средство двухколесное изобретать будем?
:-)
У вас всё стандартно. А у меня - инкапсулировано в базовом классе. Мне надо только унаследоваться от этого базового класса и в нужном виде (см. мой ответ Алексею ниже) писать сеттер.

Кстати, NotifyPropertyChanged - лучше через временную переменную :

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
 protected void NotifyPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }




Алексей Кuser7320У тебя от экспешенов уже крыша поехала. :-)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
protected void SetProperty<T>(Func<T> getter, Action<T> setter, T newValue, [CallerMemberName] string propertyName = "")
{
    var oldValue = getter();

    if (!EqualityComparer<T>.Default.Equals(oldValue, newValue))
    {
        setter(newValue);
        OnPropertyChanged(propertyName);
    }
}


Спасибо. Сеттер, конечно, чего-то разросся:

Код: c#
1.
set { SetProperty(() => _model.A, newValue => _model.A = newValue, value); }



Надеюсь, больше косяков не всплывёт, а то, если ещё придётся сеттер усложнять, то придётся, наверное, бросить эту затею с универсальным сеттером.
...
Рейтинг: 0 / 0
Универсальный setter
    #38535854
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КИли вообще вот так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
class MyEntity
{
    public virtual int Value { get; set; }
}

// Там внутри через Emit замутить потомка указанного класса, перекрыть виртуальное
// свойство и сгенерировать в него что хочешь.
var obj = NotificationFactory.Create<MyEntity>();


Тут пример реализации.
Пока что моё своёство с двумя лямбдами выглядит приятнее. ))
...
Рейтинг: 0 / 0
25 сообщений из 65, страница 2 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Универсальный setter
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]