ПредишенСледващото

Внимателно, реални договори класове могат да се различават от официалната 8

  • 11.24.15 01:35 •
  • FiresShadow •
  • • # 271533
  • • Habrahabr
  • 16 •
  • 7600

- като Forbes, само по-добре.

Накратко, в тази статия ще се съсредоточи върху управлението на наследството Лиска, разликата NotifyCollectionChangedAction.Reset договори в версии на .NET Framework 4 и .NET Framework 4.5. и кой от двата договора, истинската и какво - е погрешна.



По силата на принципа на Liski. получен клас има базов клас наследи договора (с възможност за добавяне на неговата специфичност не противоречи на първоначалния договор).

Ето един пример. Представете си, че методът Добави Списък-и виртуалното. Ако създадете наследник от Списък<>, Методът за добавяне в него трябва да бъдат добавени към колекцията на един елемент. Ако елементът ще бъде добавен само при определени условия, или да се добави към елемента и партньора му, потребителски код, който се надява, че след разговора Добави граф нараства с точно една става неизползваем. Трябва да се очаква поведението наследява класа за код, който използва тип променлива база.

Сега нека си представим, че ще използвате в кода си Списък<>. Ако се съди по добавете име и параметри (един елемент), метод за добавяне на елемент към колекцията. Вие току-що използва листа, и сме уверени, че начина, по който тя е. Можете да попитате колегите, и той не се поколеба да се потвърди, че това е така. Но нека за момент си представим, че вие ​​отидете на MSDN, вижте документацията, и тя казва, че Добавяне просто "да промени първоначалното събиране", т.е. Тя се прави нищо. В този случай, ние наричаме договора, който е характерен за базовия клас, и на която всички разчитат, вярно. и този, който е описан в документацията - формално.

При създаване на клас наследник, трябва да разчита на официалната поведението, а не истински, официално, че няма да се счупи нещо, но всъщност създават бомба, че някога може да създаде за някой (може би не за вас) проблеми.

ПРИМЕР различия и официален договор вярно - NotifyCollectionChangedAction.Reset. Преди версия 4.5 Reset означава, че съдържанието на колекцията е променило драстично. Което означава "силен"? За някой, който да добавите към трите елемента на голяма промяна, а за някой, който не.

Като цяло, Reset означава "събиране променен, колкото искате." От версия 4.5 Reset е започнало да означава събирането на почистване. Някои може да смятат, че тази промяна беше направена напразно, защото тя се разпада обратна съвместимост, но аз бих казал, че е направено както трябва, момчета - те забелязали, във времето, че истинските коефициентите с официален договор, както и своевременно да коригират грешката си. Използването ObservableCollection, можете да се срещнете Reset, само ако Clear метод е наречен от един обект (). Програмистите, които работят редовно с ObservableCollection, свикнали с него и да го разгледат в норма. "Когато могат да се срещнат Reset», - можете да ги помолите, и те не се поколеба да отговори на: "Когато бях призован Clear». Естествено, те интуитивно чувстват, че това поведение, което се превърна в де факто стандарт, който трябва да се поддържа и наследници. Ето защо, документацията трябва да се каже, че Reset - почистване колекция знак.

Да обобщим: ако изпълни наследник, се основава на най-конкретна и специфична договора, включително формално и вярно. Ако използвате клас, позовавайки се на най-малко на конкретния договор, включително формално и вярно.

Използването на Начално състояние, смятат, че това може да означава нищо. Наследяването на ObservableCollection, смятат, че е чист Reset колекция.

Послепис Ако проявявате интерес, по мое мнение на Начално състояние, считам, че разработчиците на ObservableCollection клас трябва да напуснат Reset-и договора във вида, в който е днес (почистване колекция знак), но добави към елемента за трансфер, сигнализирайки, че събиране променен, колкото искате, и които няма да бъдат използвани в оригиналната ObservableCollection. Фактът, че само един трансфер елемент, сигнализиране, че променените няколко елементи на събирането - нулиране, останалите елементи на прехвърлянето сигнал за промяна на един елемент. Един ден, за да се постигне приемливо представяне, за първи път е необходим един програмист да се промени няколко елементи в колекцията, и след това да изпратите точно един сигнал за промяна на колекцията. И той не е имал друг избор, освен да е сигнал за промяна в събирането на своя приемник от ObservableCollection от Reset-и, при липса на други алтернативи.

Така че аз мисля, че документацията за промяна се реши един проблем, но в същото време е създаден още един (за което решения трябва да се добави още един елемент в прехвърлянето). Това е смешно, но понякога неизползваните резервираните елементи могат да се възползват.

Обикновено NotifyCollectionChangedEventArgs съдържа NewItems свойства и OldItems, които могат да съдържат един или повече обекти. С тези думи единственият елемент на изброяване, сигнализирайки, че промененият няколко елемента колекция - Reset не е вярно по принцип. Добавяте и премахвате само може да сигнализира няколко промени. И това е един истински договор, а в MSDN Определете официално: че тези действия могат да бъдат само един елемент.

Но на практика, като част от .Net Framework нито един компонент, който работи правилно с (NewItems.Count> 1) и (OldItems.Count> 1). В най-добрия, по изключение се изхвърля, а в най-лошия - всички елементи, с изключение на първата са просто игнорирани.

Това не означава, че тази функционалност не мога да използвам в техните компоненти, не е тя? Тъй като тези свойства са там и те са попълнени правилно, когато създавате инстанция NotifyCollectionChangedEventArgs класа, такава възможност да е ясно предвидено.

Добавяте и премахвате само може да сигнализира няколко промени.
Работа с ObserverableCollection, трябва да се практикува най-малко веднъж се сблъскват с този случай? Можете ли да дадете пример, моля?
Не съществува метод ObserverableCollection AddRange. Всеки път, когато методът Добави (което отнема като параметър един елемент) събитие се задейства, което от NewItems винаги е точно един елемент. Така че за NotifyCollectionChangedAction.Add това, което е написано в MSDN вярно на практика.

Аз може лесно да бъде наследен от ObservableCollection<> и добавете метод AddRange и дори RemoveRange, това, което правя в практиката и, ако имам нужда от него. Освен това, мога да реализирам колекцията си (например, ObservableHashSet<>) Използване INotifyCollectionChanged интерфейс. В това изпълнение, по същия начин, може да бъде AddRange методи и RemoveRange. по принцип даде код или съобщение е ясно?

Горната статия съвети относно избора на двата договора е от значение, независимо от това дали договора интуитивни очаквания, или двата договора са формални. Отново, ако решите да реализирате наследник, се основава на най-конкретна и специфична договора между двете.
Официално договор в .NET Framework 4 казва Добави означава "един или повече елементи са добавени към колекцията.». Официалното договора за .NET Framework 4.5 Add - «артикул е добавен към колекцията.».
По този начин, както казвате, нарушите обществения официално договора от версия 4.5.
Нарушаване на договора, който е интуитивен очаквания - темата е тънка и holivarnaya, но това е нарушение на официален договор - безспорен факт. Аз препоръчвам да използвате договора наследство с най-големите ограничения - т.е., добавяне на един елемент, докато при употреба - с най-малко ограничения, т.е. добавяне на няколко елемента.

изпълнение свален (-1)
но легализирани творчески програмисти, които не са в състояние да прочете спецификацията (100500)
Съгласен съм, аз просто пише, че
Така че аз мисля, че документацията за промяна се реши един проблем, но в същото време е създаден още един (за които се нуждаят от решения, за да добавите още един елемент в изброяването)

И всички проблеми, които не са с вид на "истински договор", но със стари грешки в изпълнението.
Във всеки неясна ситуация, най-лесният начин да не се колебайте да обвинявам целия крайните изпълнители. Все пак, нека да разгледаме защо крайните изпълнители изпълняват "контролира кривите на предлагане WPF» така? Може би те са били обидени от целият свят садисти, умишлено е направил грешка? Това звучи налудничаво. И може би интуитивните им очаквания за поведението на ObservableCollection различно от това, което е написано в MSDN. Това звучи правдоподобно. Така че, има проблем - интуитивни очаквания за по-голямата част от разработчиците не съвпада с описанието в документацията. Какво може да има решение? Е, най-лесният начин да не се колебайте да се прехвърли отговорността за решаване на проблема в последните изпълнителите. Подобно, момчета, наизуст цялата MSDN и да го повтарят редовно. Това ще ви помогне да се отървете от буболечки? Не мисля, че това ще помогне. Вариант две - да се направи интуитивни очаквания за по-голямата част от програмисти да съответства на описанието в документацията. Ето как се оцени случая с промените в документацията. Ако има конструктивна критика - Ще се радвам да чуя мнението на някой друг. Фразата е "всички по-горе глупости виновни крайните изпълнители, глупости бръмбари" не са много подобни на градивната критика, тъй като той не разкрива една мисъл, но защо са глупости, защо "всички проблеми, които не са с вид на" истински договор "."

Ще обясня малко. Рамковата 4 .NET казва, че Add означава, че един или повече елементи, добавени към колекцията, и разработчиците, очевидно водени интуитивни очаквания формира ObservableCollection, което означава добавяне на един Добави обект. И ако документацията е било казано, че Добавяне означава добавяне на един елемент, тогава никой не би се опитал да продаде колекцията по начин, който е Добавяне за добавяне на още елементи, и няма да се сблъскат с проблеми. Повече би било хубаво да се уточни, че документацията Reset е почистване събиране и добавете елемент, който сигнализира произволна промяна на колекцията. Съвпадение интуитивни очаквания и формални изисквания намалява вероятността от грешки. В този случай, както изглежда, официалната документация е написана за абстрактен интерфейс и интуитивни очаквания, формирани на базата на определен клас.

Повече би било хубаво да се уточни, че документацията Reset е почистване събиране и добавете елемент, който сигнализира произволна промяна на колекцията.
Това става по-лошо. Добавяне на елемент към обществена ENUM счупи обратна съвместимост за кода директно.
И ако документацията е било казано, че Добавяне означава добавяне на един елемент, тогава никой не би се опитал да продаде колекцията по начин, който е Добавяне за добавяне на още елементи, и няма да се сблъскат с проблеми.
"Интуитивни разработчици" все пак ще са писали сами по себе си, те не прочетете документацията по дефиниция.

Няма значение - резултатът е важен.
И ако причината не е важно, как на земята е да се учим от грешките на другите? Как да не се ангажират същите грешки в бъдеще? Една от целите на моята статия - да предупреди читателите срещу такива грешки. Ако имате всичко това няма значение - добре, нали ви, можете да продължите да игнорират интуитивни очаквания на разработчиците, тя ще остане в съзнанието ти.
Всъщност, въпросът ми е, защо казвате, че "всички проблеми, които не са с вид на" истински договор "", а в отговор чух един куп емоции за нарушаването на обратна съвместимост и оценки разработчиците компетентностни WPF. Вие със сигурност ще има пълното право да емоции, и благодарение на това, че са, но нишките дискусионни по същество ще бъдат много по-приятни и полезни.

"Интуитивни разработчици" все пак ще са писали сами по себе си, те не прочетете документацията по дефиниция. Интуитивните очаквания не се формират на случаен принцип, но на базата на поведението на определен клас. Мислех, че по-скоро подробно описание на този процес, цитирани дори два примера. Мисля, че трябва редовно тролове. В последната статия имате 5 пъти попитаха за изтичане на памет и слаби събития, и аз ще 5 току-що каза: [1]. [2]. [3]. [4]. [5]. В тази статия всичко с главата надолу се опитва да се обърне.

Е, ако в действителност, че няма да има разминаване между очакванията и интуитивни документацията, необходима или класовете, които реализират интерфейса, за да добавите методи AddRange, RemoveRange, или отново да пиша документи, които могат да се добавят само един елемент.

Подкрепете проекта - споделете линка, благодаря!