Ребята, это скорее приглашение к конструктивному обсуждению, чем статья. Столкнулся с тем, что в C# как таковом нет понятия «состояния», а точнее — нет встроенной удобной возможности запомнить состояние сложного объекта в определенный момент, чтобы потом легко сравнивать, или другие объекты такого же типа находятся в таком же состоянии? Ниже я предлагаю пример — как бы это могло выглядеть.

Какой-нибудь пользовательский класс
class Test
{
    [StateAtt(StateCompareOption.AnyButNotThis)] // любое значение, кроме указанного
    public double somefiled;

    public double anothersomefiled; // этому полю атрибут не присвоен - оно в сравнении не участвует

    [StateAtt(StateCompareOption.ExactlyLikeThis)] // только такое значение
    public string StringProp { get; set; }

    public int IntProp { get; set; } // этому свойству атрибут не присвоен - оно тоже игнорируется

    public Test(string StringProp, int IntProp, double somefiled, double anothersomefield)
    {
        this.StringProp = StringProp;
        this.IntProp = IntProp;
        this.somefiled = somefiled;
        this.anothersomefiled = anothersomefield;
    }
}



Test a1 = new Test("text", 1, 50.4251, 34);

State<Test> state = State<Test>.CreateState(a1);

Test a2 = new Test("text", 1, 50.4252, 34);

state.IsInTheSameState(a2).ToString().ToConsole(); // вернет true


Ребята, хочу спросить ваше мнение. Как считаете, будет ли такой инструмент полезен в разработке?

Комментарии (12)


  1. bobermaniac
    03.11.2015 17:28

    А живой рабочий пример есть, когда это бывает полезно?


    1. 52hertz
      03.11.2015 17:36

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


  1. shai_hulud
    03.11.2015 17:39
    +2

    btw для вопросов есть спец. ресурс Toster.ru.

    А так тут есть уже сравниватель, habrahabr.ru/post/269699, а клонировать объект как эталон можно через MemberwiseClose


  1. dobriykot
    03.11.2015 17:39

    Пока вообще непонятно, зачем это все нужно.


  1. Alvaro
    03.11.2015 17:39

    Вы бы более развернуто что ли написали, где это надо и в чем необходимость именно стандартного решения, а не библиотеки из nuget. Да и если это и нужно(в чем я пока сильно сомневаюсь), то скорее стандартной библиотеке, а никак не языку.


  1. lair
    03.11.2015 18:44
    +7

    Столкнулся с тем, что в C# как таковом нет понятия «состояния»

    Есть. Набор значений внутри определенного объекта и есть его состояние.

    нет встроенной удобной возможности запомнить состояние сложного объекта в определенный момент,

    А зачем?

    Все, что вы описываете, прекрасно реализуется с помощью паттерна (внезапно) State, превращения этого внутреннего состояния в неизменное (т.е., смена состояние — полная замена объекта, описывающего состояние), и сравнения этих состояний. Ну да, можно нафигачить nuget-пакетик, если где-то реально часто встречается.


  1. vintage
    03.11.2015 22:49

    Вам нужен getHashCode или как он там в шарпе называется.


    1. lam0x86
      04.11.2015 01:27

      Можете пояснить свою мысль?


  1. shai_hulud
    03.11.2015 23:13

    Есть вариант складывать всё «состояние» в struct, а его в тело класса, а потом сравнивать эти struct'ы. Копирование и сравнение идёт в комплекте.


  1. lam0x86
    04.11.2015 00:44

    pls see below


    1. lam0x86
      04.11.2015 00:57

      На сколько я понял, метод «IsInSameState» — это что-то вроде расширенного Equals.

      Объект может иметь различный смысл в разных ситуациях. На пальцах, скажем, есть объект
      Старушка = new Человек {Паспорт = «4606 456356645» Возраст = 88, Пол = Женский, ОтношениеККурению = СмолитКакПаровоз}

      Есть сервисы IПенсионныйФонд и IОбществоПоБорьбеСРаком

      Для сервиса IПенсионныйФонд не так уж важно, сколько лет стукнуло бабуле. Паспорт совпадает — значит, она и есть.
      Для IОбществоПоБорьбеСРаком паспорт вообще не важен, зато Возраст — критерий для сравнения.

      В общем, что я хотел сказать: нельзя State задавать атрибутами. Для разных ситуаций состояние можно интерпретировать по-разному. Я не знаю, с какого языка Вы почерпнули сей паттерн, но мне кажется, данный подход (с атрибутами, как Вы предложили), там долго не продержится.
      А вообще, наверняка кто-то сталкивался с подобным, надо только поискать.


      1. lam0x86
        04.11.2015 01:07

        И как архитектурный дизайн, я бы предложил что-нибудь типа stateless-класса StateChecker, который должен единожды инициализироваться правилами проверки состояния. Его можно было бы инстанциировать в нужных местах кода или по аналогии с IEqualityComparer<T> иметь статические синглтоны вроде EqualityComparer.Default для стандартных ситуаций. Но тогда вопрос — чем это отличается, собственно, от IEqualityComparer<T>? Если в нужных местах можно игнорировать какое-то свойство объекта, пожалуйста — напиши свой компаратор, сравнивающий всё, кроме этого свойства.