<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3365658765336324348</id><updated>2011-12-23T11:03:50.513+04:00</updated><category term='Guidelines'/><category term='C#'/><category term='Life'/><category term='Diagnostics'/><category term='Bugs'/><category term='WPF'/><category term='BCL'/><category term='Snippets'/><title type='text'>C# Snippets</title><subtitle type='html'>Кусочки кода</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-2683225338799179627</id><published>2011-11-15T10:59:00.001+04:00</published><updated>2011-11-18T11:31:10.165+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Как написать Equatable или Comparable тип</title><content type='html'>&lt;p&gt;
Не редко возникает необходимость добавить к типу данных, созданных вами, возможности для сравнения экземпляров друг с другом или с другими объектами. В C#, так уж повелось, это не самая простая операция, чреватая и ошибками и избыточным кодом. Связано это с тем, как мне кажется, что в различных источниках приведены самые разные "паттерны" реализации сравнения и люди, начитавшись (кто-то больше, кто-то меньше) иногда смешивают подходы в одном примере с подходами в другом да добавляют ещё и что-то от себя лично :) Таким образом "паттерны" размножаются, служа пищей для размышления и источником вдохновения для следующего поколения программистов, которые читают доставшийся им код, другие публикации и придумывают свои "паттерны". 
&lt;/p&gt;
&lt;p&gt;
Так же, свою руку к путанице, на первый взгляд, приложили и сами разработчики дотнета, описав "запутанные" правила, по которым должно быть реализовано сравнение (смотрите &lt;a href="http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx" target="_blank"&gt;Notes to Implementers&lt;/a&gt; /* Даже адрес по ссылке заканчивается на "АК-47", даже на два :о) */). Но это только так кажется, на самом деле правила весьма просты и, наоборот, позволяют просто и безошибочно реализовать сравнения.
&lt;/p&gt;
&lt;p&gt;
Большой вклад по привлечению к обозначенной проблеме широкой общественности внёс &lt;a href="http://rsdn.ru/Users/Profile.aspx?uid=73" target="_blank"&gt;Чистяков Влад (VladD2)&lt;/a&gt; в своей статье "&lt;a href="http://rsdn.ru/article/csharp/ImplementingOperators.xml" target="_blank"&gt;Багодром: Реализация операторов сравнения&lt;/a&gt;", наглядно продемонстрировав, на сколько неприятны могут быть последствия плохой реализации и предложив надёжный "паттерн" решения. Ниже я лишь где-то упрощу, а где-то усложню предложенный способ (обратите внимание, что предложенный в статье способ следует использовать только для reference-типов), а так же предложу способ, который следует применять с value-типами. 
&lt;/p&gt;
&lt;p&gt;
Тренироваться будем на следующих типах, к которым сначала добавим возможность сравнения на равенство, а затем на больше-меньше.
&lt;/p&gt;
&lt;p class="code"&gt;
&lt;span class = "kw"&gt;using&lt;/span&gt; System;&lt;br/&gt;
&lt;br/&gt;
&lt;span class = "kw"&gt;internal&lt;/span&gt; &lt;span class = "kw"&gt;struct&lt;/span&gt; &lt;span class = "t"&gt;MyValue&lt;/span&gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; MyValue(&lt;span class = "kw"&gt;int&lt;/span&gt; first, &lt;span class = "kw"&gt;int&lt;/span&gt;? second) : &lt;span class = "kw"&gt;this&lt;/span&gt;() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;First = first;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Second = second;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; First { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt;? Second { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
}&lt;br/&gt;
&lt;br/&gt;
&lt;span class = "kw"&gt;internal&lt;/span&gt; &lt;span class = "kw"&gt;sealed&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;MyData&lt;/span&gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; MyData(&lt;span class = "kw"&gt;string&lt;/span&gt; name, &lt;span class = "t"&gt;MyValue&lt;/span&gt; &lt;span class = "kw"&gt;value&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Name = name ?? &lt;span class = "t"&gt;String&lt;/span&gt;.Empty;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Value = &lt;span class = "kw"&gt;value&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;string&lt;/span&gt; Name { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "t"&gt;MyValue&lt;/span&gt; Value { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
}&lt;/p&gt;
&lt;p&gt;
Мы переопределим методы &lt;span class="ic"&gt;Equals(object)&lt;/span&gt; и &lt;span class="ic"&gt;GetHashCode()&lt;/span&gt;, добавим реализацию &lt;span class="ic"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms131187.aspx" target="_blank"&gt;IEquatable&amp;lt&amp;gt;&lt;/a&gt;&lt;/span&gt;, а так же переопределим операторы &lt;span class="ic"&gt;==&lt;/span&gt; и &lt;span class="ic"&gt;!=&lt;/span&gt;. Причём собственно реализация сравнения будет находиться лишь в двух методах: &lt;span class="ic"&gt;Object::GetHashCode()&lt;/span&gt; и &lt;span class="ic"&gt;IEquatable&amp;ltT&amp;gt;::Equals(T)&lt;/span&gt; и всё остальные вызовы будут переадресованы туда и их реализация и будет "паттерном", не зависящим от логики сравнения.
&lt;/p&gt;
&lt;p class="code"&gt;
&lt;span class = "kw"&gt;internal&lt;/span&gt; &lt;span class = "kw"&gt;struct&lt;/span&gt; &lt;span class = "t"&gt;MyValue&lt;/span&gt; : &lt;span class = "t"&gt;IEquatable&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;MyValue&lt;/span&gt;&amp;gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; MyValue(&lt;span class = "kw"&gt;int&lt;/span&gt; first, &lt;span class = "kw"&gt;int&lt;/span&gt;? second) : &lt;span class = "kw"&gt;this&lt;/span&gt;() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;First = first;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Second = second;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; First { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt;? Second { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "kw"&gt;object&lt;/span&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; obj &lt;span class = "kw"&gt;is&lt;/span&gt; &lt;span class = "t"&gt;MyValue&lt;/span&gt; &amp;&amp; Equals((&lt;span class = "t"&gt;MyValue&lt;/span&gt;)obj);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; First.GetHashCode() ^ Second.GetHashCode();&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;#region&lt;/span&gt; IEquatable&amp;lt;MyValue&amp;gt; Members&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "t"&gt;MyValue&lt;/span&gt; other) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; First == other.First &amp;&amp; Second == other.Second;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;#endregion&lt;/span&gt; IEquatable&amp;lt;MyValue&amp;gt; Members&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; &lt;span class = "kw"&gt;operator&lt;/span&gt; ==(&lt;span class = "t"&gt;MyValue&lt;/span&gt; left, &lt;span class = "t"&gt;MyValue&lt;/span&gt; right) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; left.Equals(right);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; &lt;span class = "kw"&gt;operator&lt;/span&gt; !=(&lt;span class = "t"&gt;MyValue&lt;/span&gt; left, &lt;span class = "t"&gt;MyValue&lt;/span&gt; right) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; !(left == right);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
}&lt;br/&gt;
&lt;br/&gt;
&lt;span class = "kw"&gt;internal&lt;/span&gt; &lt;span class = "kw"&gt;sealed&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;MyData&lt;/span&gt; : &lt;span class = "t"&gt;IEquatable&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;MyData&lt;/span&gt;&amp;gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; MyData(&lt;span class = "kw"&gt;string&lt;/span&gt; name, &lt;span class = "t"&gt;MyValue&lt;/span&gt; &lt;span class = "kw"&gt;value&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Name = name ?? &lt;span class = "t"&gt;String&lt;/span&gt;.Empty;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;Value = &lt;span class = "kw"&gt;value&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;string&lt;/span&gt; Name { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "t"&gt;MyValue&lt;/span&gt; Value { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "kw"&gt;object&lt;/span&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; Equals(obj &lt;span class = "kw"&gt;as&lt;/span&gt; &lt;span class = "t"&gt;MyData&lt;/span&gt;);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; Name.GetHashCode() ^ Value.GetHashCode();&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;#region&lt;/span&gt; IEquatable&amp;lt;MyData&amp;gt; Members&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "t"&gt;MyData&lt;/span&gt; other) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; other != &lt;span class = "kw"&gt;null&lt;/span&gt;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;&amp; Name == other.Name&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;&amp; Value == other.Value;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;#endregion&lt;/span&gt; IEquatable&amp;lt;MyData&amp;gt; Members&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; &lt;span class = "kw"&gt;operator&lt;/span&gt; ==(&lt;span class = "t"&gt;MyData&lt;/span&gt; left, &lt;span class = "t"&gt;MyData&lt;/span&gt; right) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; Equals(left, right);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; &lt;span class = "kw"&gt;operator&lt;/span&gt; !=(&lt;span class = "t"&gt;MyData&lt;/span&gt; left, &lt;span class = "t"&gt;MyData&lt;/span&gt; right) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; !(left == right);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
}&lt;/p&gt;
&lt;p&gt;
Разница между реализацией в значимом и ссылочном типах следующая:
&lt;ul&gt;
  &lt;li&gt;Проверка типа аргумента в значимом типе в реализации &lt;span class="ic"&gt;Object::Equals(object)&lt;/span&gt; "двойная" - сначала посредством &lt;span class = "ikw"&gt;is&lt;/span&gt;, а потом при приведении типа, но по-другому никак. С сылочным типом ситуация лучше - тут используется оператор &lt;span class = "ikw"&gt;as&lt;/span&gt;, который одновременно и проверяет тип и делает приведение типа. Причём, если тип аргумента не подходящий, &lt;span class = "ikw"&gt;as&lt;/span&gt; вернёт &lt;span class = "ikw"&gt;null&lt;/span&gt;, а эта ситуация рассматривается в следующем пункте.&lt;/li&gt;
  &lt;li&gt;При реализации &lt;span class="ic"&gt;IEquatable&amp;lt;T&amp;gt;::Equals(T)&lt;/span&gt; в ссылочном типе всегда проверяйте аргумент на &lt;span class = "ikw"&gt;null&lt;/span&gt; и возвращайте &lt;span class = "ikw"&gt;false&lt;/span&gt; если проверка удалась, ибо "x.Equals(null) returns false" (&lt;a href="http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx" target="_blank"&gt;Notes to Implementers&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;Реализация оператора "&lt;span class="ic"&gt;==&lt;/span&gt;" проста - в значимом типе мы просто вызываем экземплярный типизированный &lt;span class="ic"&gt;Equals&lt;/span&gt;, а в ссылочном - статический &lt;a href="http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx" target="_blank"&gt;&lt;span class="ic"&gt;Object::Equals(object, object)&lt;/span&gt;&lt;/a&gt;, который сначала проверит аргументы на &lt;span class = "ikw"&gt;null&lt;/span&gt;, а потом вызовет тот же самый экземплярный типизированный &lt;span class="ic"&gt;Equals&lt;/span&gt; (только если оба аргумента не пустые). Почему-то разработчики часто забывают об этом удобнейшем методе и самостоятельно выписывают велосипеды a-la
&lt;div class = "code"&gt;
&lt;span class = "kw"&gt;if&lt;/span&gt;(ReferenceEquals(left, &lt;span class = "kw"&gt;null&lt;/span&gt;)) {&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; ReferenceEquals(right, &lt;span class = "kw"&gt;null&lt;/span&gt;);&lt;br/&gt;
} &lt;span class = "kw"&gt;else if&lt;/span&gt;(ReferenceEquals(right, &lt;span class = "kw"&gt;null&lt;/span&gt;)) {&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&lt;span class = "kw"&gt;return false&lt;/span&gt;;&lt;br/&gt;
}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
или
&lt;div class = "code"&gt;
&lt;span class = "kw"&gt;if&lt;/span&gt;((&lt;span class = "kw"&gt;object&lt;/span&gt;)left == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; (&lt;span class = "kw"&gt;object&lt;/span&gt;)right == &lt;span class = "kw"&gt;null&lt;/span&gt;;&lt;br/&gt;
} &lt;span class = "kw"&gt;else if&lt;/span&gt;((&lt;span class = "kw"&gt;object&lt;/span&gt;)right == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&lt;span class = "kw"&gt;return false&lt;/span&gt;;&lt;br/&gt;
}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
что совершенно не требуется.
&lt;/li&gt;
&lt;/ul&gt;
Отдельно надо остановиться на следующем моменте: часто можно видеть при реализации равенства в ссылочном типе проверку, что мы сравниваем объект с самим собой. Виноват в этом, мне кажется, Джеффри Рихтер, начавший с этого соответствующую главу своей книги. Я этим &lt;i&gt;обычно&lt;/i&gt; не пользуюсь, ибо  1) не часто приходится сравнивать объекты друг с другом и большого выигрыша не получается 2) на каплю, но усложняется логика сравнения, что, учитывая пункт первый, становится не нужным. Однако, если вы считаете, что такое сравнение добавит вам производительности, то реализация &lt;span class="ic"&gt;IEquatable&amp;lt;T&amp;gt;::Equals(T)&lt;/span&gt; может быть примерно такой:
&lt;div class = "code"&gt;
&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "t"&gt;MyData&lt;/span&gt; other) {&lt;br/&gt;
&amp;nbsp; &lt;span class = "kw"&gt;return&lt;/span&gt; RefenrenceEquals(other, &lt;span class = "kw"&gt;this&lt;/span&gt;) || other != &lt;span class = "kw"&gt;null&lt;/span&gt;&lt;br/&gt;
&amp;nbsp; &amp;nbsp; &amp;&amp; Name == other.Name&lt;br/&gt;
&amp;nbsp; &amp;nbsp; &amp;&amp; Value == other.Value;&lt;br/&gt;
}&lt;br/&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;
Для завершения раздела о реализации равенства скажу, что сравнение незапечатанных (обратили внимание, что класс &lt;span class = "ic"&gt;MyData&lt;/span&gt; обозначен как &lt;span class = "ikw"&gt;sealed&lt;/span&gt;?) ссылочных типов достойно отдельной статьи.
&lt;/p&gt;
&lt;p&gt;
Наконец, для упрощения написания этих шаблонных методов я использую сниппеты. Первый добавляет реализацию для значимого типа:
&lt;/p&gt;
&lt;p class="xml"&gt;
&amp;lt;&lt;span class="e"&gt;CodeSnippets&lt;/span&gt; &lt;span class="a"&gt;xmlns&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp;&amp;lt;&lt;span class="e"&gt;CodeSnippet&lt;/span&gt; &lt;span class="a"&gt;Format&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;1.0.0&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Header&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Title&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;Implements IEquatable&amp;lt;&amp;gt; interface for a value type&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Title&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Shortcut&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;eqstruct&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Shortcut&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;SnippetTypes&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;SnippetType&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;Expansion&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;SnippetType&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;SnippetTypes&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Header&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Snippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Declarations&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Literal&lt;/span&gt; &lt;span class="a"&gt;Editable&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;false&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;TypeName&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;ClassName()&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Literal&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Literal&lt;/span&gt; &lt;span class="a"&gt;Editable&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;false&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;NotImplementedException&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;SimpleTypeName(global::System.NotImplementedException)&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Literal&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Declarations&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Code&lt;/span&gt; &lt;span class="a"&gt;Language&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;CSharp&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;![CDATA[&lt;span class="cdata"&gt;public override bool Equals(object obj) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return obj is $TypeName$ &amp;&amp; Equals(($TypeName$)obj);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public override int GetHashCode() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;throw new $NotImplementedException$();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#region IEquatable&lt;$TypeName$&gt; Members&lt;br /&gt;
&lt;br /&gt;
public bool Equals($TypeName$ other) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;// Add you equals logic&lt;br /&gt;
&amp;nbsp;&amp;nbsp;//return $end$;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;throw new $NotImplementedException$();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#endregion IEquatable&lt;$TypeName$&gt; Members&lt;br /&gt;
&lt;br /&gt;
public static bool operator ==($TypeName$ left, $TypeName$ right) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return left.Equals(right);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static bool operator !=($TypeName$ left, $TypeName$ right) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return !(left == right);&lt;br /&gt;
}&lt;/span&gt;]]&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Code&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Snippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;CodeSnippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
&amp;lt;/&lt;span class="e"&gt;CodeSnippets&lt;/span&gt;&amp;gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
Второй - для ссылочного типа:
&lt;/p&gt;
&lt;p class="xml"&gt;
&amp;lt;&lt;span class="e"&gt;CodeSnippets&lt;/span&gt; &lt;span class="a"&gt;xmlns&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp;&amp;lt;&lt;span class="e"&gt;CodeSnippet&lt;/span&gt; &lt;span class="a"&gt;Format&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;1.0.0&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Header&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Title&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;Implements IEquatable&amp;lt;&amp;gt; interface for a reference type&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Title&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Shortcut&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;eqclass&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Shortcut&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;SnippetTypes&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;SnippetType&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;Expansion&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;SnippetType&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;SnippetTypes&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Header&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Snippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Declarations&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Literal&lt;/span&gt; &lt;span class="a"&gt;Editable&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;false&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;TypeName&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;ClassName()&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Literal&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Literal&lt;/span&gt; &lt;span class="a"&gt;Editable&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;false&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;NotImplementedException&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;ID&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;span class="t"&gt;SimpleTypeName(global::System.NotImplementedException)&lt;/span&gt;&amp;lt;/&lt;span class="e"&gt;Function&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Literal&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Declarations&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span class="e"&gt;Code&lt;/span&gt; &lt;span class="a"&gt;Language&lt;/span&gt;=&amp;quot;&lt;span class="v"&gt;CSharp&lt;/span&gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;![CDATA[&lt;span class="cdata"&gt;public override bool Equals(object obj) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return Equals(obj as $TypeName$);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public override int GetHashCode() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;throw new $NotImplementedException$();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#region IEquatable&lt;$TypeName$&gt; Members&lt;br /&gt;
&lt;br /&gt;
public bool Equals($TypeName$ other) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;// Add you equals logic&lt;br /&gt;
&amp;nbsp;&amp;nbsp;//return other != null &amp;&amp; $end$;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;throw new $NotImplementedException$();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#endregion IEquatable&lt;$TypeName$&gt; Members&lt;br /&gt;
&lt;br /&gt;
public static bool operator ==($TypeName$ left, $TypeName$ right) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return Equals(left, right);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static bool operator !=($TypeName$ left, $TypeName$ right) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;return !(left == right);&lt;br /&gt;
}&lt;/span&gt;]]&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Code&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;Snippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
 &amp;nbsp;&amp;lt;/&lt;span class="e"&gt;CodeSnippet&lt;/span&gt;&amp;gt;&lt;br /&gt;
&amp;lt;/&lt;span class="e"&gt;CodeSnippets&lt;/span&gt;&amp;gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
Реализация сравнения на больше-меньше будет заметно легче - в ней нет подводных камней, достаточно всё сделать аккуратно. Следующий пост постараюсь посвятить ей.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-2683225338799179627?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/2683225338799179627/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/11/equatable-comparable.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/2683225338799179627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/2683225338799179627'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/11/equatable-comparable.html' title='Как написать Equatable или Comparable тип'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-7253080504014148940</id><published>2011-11-05T19:22:00.000+04:00</published><updated>2011-11-05T19:23:00.462+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='BCL'/><title type='text'>Компараторы для HashSet&lt;&gt;</title><content type='html'>&lt;p&gt;
Как я попробовал показать в &lt;a href="http://viacheslav-ivanov.blogspot.com/2011/09/hashset-createsetcomparer.html"&gt;предыдущем сообщении&lt;/a&gt;, стандартная реализация компаратора для &lt;span class="ic"&gt;HashSet&amp;lt;&amp;gt;&lt;/span&gt; содержит ошибку, которая состоит в том, что при сравнении элементов хешсета может использоваться внутренний компаратор хешсета, а при расчёте хешкода всегда используется стандартный (&lt;span class="ic"&gt;EqualityComparer&amp;lt;&amp;gt;.Default&lt;/span&gt;).
&lt;/p&gt;
&lt;p&gt;
Настало время эту ошибку исправить. Вдаваясь в долгие и скучные объяснения с различными примерами можно показать, что одним методом без параметров для получения компаратора, как &lt;span class="ic"&gt;HashSet&amp;lt;&amp;gt;::CreateSetComparer()&lt;/span&gt;, нельзя вернуть универсальный компаратор на все случаи жизни. Поэтому придётся использовать два метода:
&lt;ul&gt;
&lt;li&gt;Один (без параметров) возвращает компаратор, который для сравнения элементов и расчёта хешкода всегда использует внутренний компаратор хешсета. При этом, при сравнении двух хешсетов компаратор вернёт &lt;span class="ikw"&gt;false&lt;/span&gt; в том случае, если компараторы в хешсетах не эквивалентны.&lt;/li&gt;
&lt;li&gt;Второй позволяет задать извне компаратор, который будет использоваться для сравнения элементов хешсета и расчёта хешкода.&lt;/li&gt;
&lt;/ul&gt;
Первый метод следует использовать тогда, когда вы заранее знаете, что будете сравнивать хешсеты, которые одинаково (одним и тем же компаратором) сравнивают свои собственные элементы. Второй метод позволит сравнивать произвольные хешсеты, но вы должны сами задать (с помощью компаратора) - как именно следует сравнивать элементы в этих хешсетах.
&lt;/p&gt;
&lt;p&gt;
Вот эти методы (класс &lt;span class="ic"&gt;Comparers&lt;/span&gt; у меня содержит всякое безобразие для всевозможных компараторов, например, ещё &lt;a href="http://rsdn.ru/forum/src/4322485.1.aspx"&gt;это&lt;/a&gt; и &lt;a href="http://rsdn.ru/forum/src/4330638.1.aspx"&gt;это&lt;/a&gt;):
&lt;/p&gt;
&lt;p class="code"&gt;
&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;partial&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;Comparers&lt;/span&gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt;&gt; HashSetComparer&amp;lt;T&gt;() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; &lt;span class = "t"&gt;HashSetEqualityComparer&lt;/span&gt;&amp;lt;T&gt;.Default;&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt;&gt; HashSetCustomComparer&amp;lt;T&gt;(&lt;span class = "t"&gt;IEqualityComparer&lt;/span&gt;&amp;lt;T&gt; comparer = &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; &lt;span class = "kw"&gt;new&lt;/span&gt; &lt;span class = "t"&gt;HashSetCustomEqualityComparer&lt;/span&gt;&amp;lt;T&gt;(comparer);&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
}&lt;br/&gt;
&lt;/p&gt;
&lt;p&gt;
Первый метод всегда возвращает один и тот же объект, так логика работы этого компаратора не зависит от каких либо внешних факторов. Второй метод возвращает компаратор, параметризованный другим компаратором, который будет использоваться для сравнения элементов хешсета, поэтому каждый раз создаётся новый объект. Рассмотрим устройство и особенности этих объектов.
&lt;/p&gt;
&lt;p&gt;
Первый компаратор:
&lt;/p&gt;
&lt;p class="code"&gt;
&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;partial&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;Comparers&lt;/span&gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;[&lt;span class = "t"&gt;Serializable&lt;/span&gt;]&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;sealed&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;HashSetEqualityComparer&lt;/span&gt;&amp;lt;T&gt; : &lt;span class = "t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt;&gt;&lt;br/&gt;
 &amp;nbsp;{&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;const&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; MagicNumber = 13;&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;static&lt;/span&gt; HashSetEqualityComparer() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;Default = &lt;span class = "kw"&gt;new&lt;/span&gt; &lt;span class = "t"&gt;HashSetEqualityComparer&lt;/span&gt;&amp;lt;T&gt;();&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;new&lt;/span&gt; &lt;span class = "t"&gt;HashSetEqualityComparer&lt;/span&gt;&amp;lt;T&gt; Default { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; x, &lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; y) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;if&lt;/span&gt;(x == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; y == &lt;span class = "kw"&gt;null&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;} &lt;span class = "kw"&gt;else&lt;/span&gt; &lt;span class = "kw"&gt;if&lt;/span&gt;(y == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; &lt;span class = "kw"&gt;false&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;} &lt;span class = "kw"&gt;else&lt;/span&gt; &lt;span class = "kw"&gt;if&lt;/span&gt;(!Equals(x.Comparer, y.Comparer)) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; &lt;span class = "kw"&gt;false&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; x.SetEquals(y);&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode(&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;if&lt;/span&gt;(obj == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; 0;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; obj.Aggregate(0, (hash, item) =&gt;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hash ^ (obj.Comparer.GetHashCode(item) &amp; 0x7FFFFFFF));&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "kw"&gt;object&lt;/span&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; obj &lt;span class = "kw"&gt;is&lt;/span&gt; &lt;span class = "t"&gt;HashSetEqualityComparer&lt;/span&gt;&amp;lt;T&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; MagicNumber;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
}&lt;br/&gt;
&lt;/p&gt;
&lt;p&gt;
Особенности:
&lt;ul&gt;
&lt;li&gt;Данный компаратор умеет сравнивать только хешсеты с одинаковыми компараторами, зато достаточно оптимально.&lt;/li&gt;
&lt;li&gt;При вычислении хешкода для получения хешкода элемента хешсета используется внутренний компаратор хешсета.&lt;/li&gt;
&lt;li&gt;Любые два экземпляра этого компаратора всегда равны между собой (а экземпляров может быть несколько, так как конструктор открытый). Вообще, реализация сравнения в компараторах - отдельная тема. Обратите внимание, что для сравнения компараторов здесь используется метод &lt;span class="ic"&gt;Object::Equals(&lt;span class="ikw"&gt;object&lt;/span&gt;, &lt;span class="ikw"&gt;object&lt;/span&gt;)&lt;/span&gt;, а не оператор сравнения (как, например, в родной реализации компаратора).&lt;/li&gt;
&lt;li&gt;&lt;span class="ic"&gt;MaficNumber&lt;/span&gt;, не равный нулю, используется из-за того, что равный нулю хешкод обычно возвращается для объектов, имеющих значение &lt;span class="ikw"&gt;null&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
Второй компаратор:
&lt;/p&gt;
&lt;p class="code"&gt;
&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;static&lt;/span&gt; &lt;span class = "kw"&gt;partial&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;Comparers&lt;/span&gt;&lt;br/&gt;
{&lt;br/&gt;
 &amp;nbsp;[&lt;span class = "t"&gt;Serializable&lt;/span&gt;]&lt;br/&gt;
 &amp;nbsp;&lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "kw"&gt;sealed&lt;/span&gt; &lt;span class = "kw"&gt;class&lt;/span&gt; &lt;span class = "t"&gt;HashSetCustomEqualityComparer&lt;/span&gt;&amp;lt;T&gt; : &lt;span class = "t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt;&gt;&lt;br/&gt;
 &amp;nbsp;{&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; HashSetCustomEqualityComparer(&lt;span class = "t"&gt;IEqualityComparer&lt;/span&gt;&amp;lt;T&gt; comparer = &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;Comparer = comparer ?? &lt;span class = "t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;T&gt;.Default;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;private&lt;/span&gt; &lt;span class = "t"&gt;IEqualityComparer&lt;/span&gt;&amp;lt;T&gt; Comparer { &lt;span class = "kw"&gt;get&lt;/span&gt;; &lt;span class = "kw"&gt;set&lt;/span&gt;; }&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; x, &lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; y) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;if&lt;/span&gt;(x == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; y == &lt;span class = "kw"&gt;null&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;} &lt;span class = "kw"&gt;else&lt;/span&gt; &lt;span class = "kw"&gt;if&lt;/span&gt;(y == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; &lt;span class = "kw"&gt;false&lt;/span&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;} &lt;span class = "kw"&gt;else&lt;/span&gt; &lt;span class = "kw"&gt;if&lt;/span&gt;(Equals(x.Comparer, y.Comparer) &amp;&amp; Equals(x.Comparer, Comparer)) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; x.SetEquals(y);&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;var&lt;/span&gt; set = &lt;span class = "kw"&gt;new&lt;/span&gt; &lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt;(x, Comparer);&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; set.SetEquals(y);&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode(&lt;span class = "t"&gt;HashSet&lt;/span&gt;&amp;lt;T&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;if&lt;/span&gt;(obj == &lt;span class = "kw"&gt;null&lt;/span&gt;) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; 0;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;span class = "c"&gt;//if&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; obj.Aggregate(0, (hash, item) =&gt;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hash ^ (Comparer.GetHashCode(item) &amp; 0x7FFFFFFF));&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;bool&lt;/span&gt; Equals(&lt;span class = "kw"&gt;object&lt;/span&gt; obj) {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;var&lt;/span&gt; other = obj &lt;span class = "kw"&gt;as&lt;/span&gt; &lt;span class = "t"&gt;HashSetCustomEqualityComparer&lt;/span&gt;&amp;lt;T&gt;;&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; other != &lt;span class = "kw"&gt;null&lt;/span&gt; &amp;&amp; Equals(other.Comparer, Comparer);&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;public&lt;/span&gt; &lt;span class = "kw"&gt;override&lt;/span&gt; &lt;span class = "kw"&gt;int&lt;/span&gt; GetHashCode() {&lt;br/&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class = "kw"&gt;return&lt;/span&gt; Comparer.GetHashCode();&lt;br/&gt;
 &amp;nbsp; &amp;nbsp;}&lt;br/&gt;
 &amp;nbsp;}&lt;br/&gt;
}&lt;br/&gt;
&lt;/p&gt;
&lt;p&gt;
Особенности:
&lt;ul&gt;
&lt;li&gt;Если компараторы сравниваемых хешсетов эквивалентны как между собой, так и с внутренним компаратором, будет использован более оптимальный способ сравнения.&lt;/li&gt;
&lt;li&gt;При вычислении хешкода для получения хешкода элемента хешсета используется собственный компаратор.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
Конечно, можно было бы обойтись и одним методом и одним классом компаратора, но было бы больше проверок и ветвлений, поэтому я выбрал небольшое дублирование кода (реализация &lt;span class = "ic"&gt;GetHashCode()&lt;/span&gt; у компараторов отличается только используемым внутри компаратором), но более простые классы.
&lt;/p&gt;
&lt;p&gt;
В заключении надо сказать, что похожие проблемы есть и у компаратора, который стандартная библиотека предоставляет для &lt;span class = "ic"&gt;SortedSet&lt;&gt;&lt;/span&gt;. Я, как мог, постарался описать их на форуме BCL (&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/6826304a-eda9-4af8-bd60-6db03b89e41e"&gt;здесь&lt;/a&gt;) и узнал, что, оказывается, это всё by design, то есть "так и задумано". Хотя это может быть и ошибочным мнением. Отдельно на коннект сообщать об этой, второй, похожей проблеме нет желания - много писанины с заранее известным результатом. Буду надеяться, что справившись с опубликованной багой они просмотрят аналогичный код и приведут его в соответствие.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-7253080504014148940?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/7253080504014148940/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/11/hashset.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7253080504014148940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7253080504014148940'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/11/hashset.html' title='Компараторы для HashSet&lt;&gt;'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>2</thr:total><georss:featurename>Saint-Petersburg, Russia</georss:featurename><georss:point>59.939039 30.315785</georss:point><georss:box>59.430006 29.052357500000003 60.448072 31.5792125</georss:box></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-4275194126766291573</id><published>2011-09-28T21:10:00.000+04:00</published><updated>2011-09-28T22:14:14.393+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='BCL'/><title type='text'>Баг в реализации HashSet&lt;&gt;::CreateSetComparer()</title><content type='html'>Не правильно работает компаратор, возвращаемый методом &lt;a href="http://msdn.microsoft.com/en-us/Library/bb335475.aspx"&gt;&lt;span class="ic"&gt;CreateSetComparer&lt;/span&gt;&lt;/a&gt; класса &lt;span class="it"&gt;HashSet&lt;/span&gt;&lt;span class="ic"&gt;&amp;lt;&amp;gt;&lt;/span&gt;. Пример кода, демонстрирующий ошибку:&lt;br /&gt;
&lt;p class="code"&gt;&lt;span class="kw"&gt;using&lt;/span&gt; System;&lt;br /&gt;
&lt;span class="kw"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;
&lt;span class="kw"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="kw"&gt;internal sealed class&lt;/span&gt; &lt;span class="t"&gt;MyItem&lt;/span&gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="t"&gt;MyItem&lt;/span&gt;(&lt;span class="kw"&gt;int&lt;/span&gt; number, &lt;span class="kw"&gt;string&lt;/span&gt; text) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Number = number;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text = text ?? &lt;span class="t"&gt;String&lt;/span&gt;.Empty;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;public int&lt;/span&gt; Number { &lt;span class="kw"&gt;get&lt;/span&gt;; &lt;span class="kw"&gt;private set&lt;/span&gt;; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;public string&lt;/span&gt; Text { &lt;span class="kw"&gt;get&lt;/span&gt;; &lt;span class="kw"&gt;private set&lt;/span&gt;; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="kw"&gt;internal sealed class&lt;/span&gt; &lt;span class="t"&gt;MyItemComparer&lt;/span&gt; : &lt;span class="t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class="t"&gt;MyItem&lt;/span&gt;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;public override bool&lt;/span&gt; Equals(&lt;span class="t"&gt;MyItem&lt;/span&gt; x, &lt;span class="t"&gt;MyItem&lt;/span&gt; y) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;if&lt;/span&gt;(x == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; y == &lt;span class="kw"&gt;null&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span class="kw"&gt;else if&lt;/span&gt;(y == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return false&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span class="kw"&gt;else&lt;/span&gt; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class="kw"&gt;int&lt;/span&gt;&amp;gt;.Default.Equals(x.Number, y.Number);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;span class="c"&gt;//if&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;public override int&lt;/span&gt; GetHashCode(&lt;span class="t"&gt;MyItem&lt;/span&gt; obj) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;if&lt;/span&gt;(obj == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;span class="c"&gt;//if&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="t"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span class="kw"&gt;int&lt;/span&gt;&amp;gt;.Default.GetHashCode(obj.Number);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="kw"&gt;internal static class&lt;/span&gt; &lt;span class="t"&gt;Program&lt;/span&gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;private static void&lt;/span&gt; Main() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; itemComparer = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="t"&gt;MyItemComparer&lt;/span&gt;();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; set1 = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="t"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span class="t"&gt;MyItem&lt;/span&gt;&amp;gt;(itemComparer) { &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="t"&gt;MyItem&lt;/span&gt;(1, &lt;span class="s"&gt;"One"&lt;/span&gt;), };&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; set2 = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="t"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span class="t"&gt;MyItem&lt;/span&gt;&amp;gt;(itemComparer) { &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="t"&gt;MyItem&lt;/span&gt;(1, &lt;span class="s"&gt;"1"&lt;/span&gt;), };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; test = set1.SetEquals(set2);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="t"&gt;Debug&lt;/span&gt;.Assert(test); &lt;span class="c"&gt;// OK&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; setComparer = &lt;span class="t"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span class="t"&gt;MyItem&lt;/span&gt;&amp;gt;.CreateSetComparer();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; equals = setComparer.Equals(set1, set2);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="t"&gt;Debug&lt;/span&gt;.Assert(equals); &lt;span class="c"&gt;// OK&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; hash1 = setComparer.GetHashCode(set1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;var&lt;/span&gt; hash2 = setComparer.GetHashCode(set2);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="t"&gt;Debug&lt;/span&gt;.Assert(hash1 == hash2, &lt;span class="s"&gt;"hash1 == hash2"&lt;/span&gt;); &lt;span class="c"&gt;// Failed&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
}&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
Ошибка заключается в том, что для двух объектов, которые компаратор считает равными, он возвращает различные хеш-коды. Происходит это в рассмотренном случае из-за того, что при рассчёте равенства используется внутренний компаратор хеш-сета (потому что компараторы оказываются равными), а вот при подсчёте хеш-кода всегда используется дефолтовый компаратор.&lt;br /&gt;
&lt;br /&gt;
Для решения моей проблемы будет достаточным написать свой аналог компаратора, в который можно будет передать кастомный компаратор элементов.&lt;br /&gt;
&lt;br /&gt;
Update: Желающие могут проголосовать за этот баг &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/691427"&gt;на коннекте&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-4275194126766291573?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/4275194126766291573/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/09/hashset-createsetcomparer.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/4275194126766291573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/4275194126766291573'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/09/hashset-createsetcomparer.html' title='Баг в реализации HashSet&lt;&gt;::CreateSetComparer()'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-5454278855952303286</id><published>2011-08-22T20:47:00.000+04:00</published><updated>2011-08-22T20:47:05.767+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BCL'/><title type='text'>О реализации сравнений /* CompareTo() */</title><content type='html'>&lt;p&gt;Почему-то не редко встречаюсь с мнением, что реализация сравнения двух знаковых целых (&lt;span class="it"&gt;Int32&lt;/span&gt;) делается (или [наиболее] эффективно может быть сделана) с помощью обычной операции вычитания, например:&lt;/p&gt;
&lt;div class="code"&gt;
&lt;span class="kw"&gt;static int&lt;/span&gt; CompareTo(&lt;span class="kw"&gt;int&lt;/span&gt; x, &lt;span class="kw"&gt;int&lt;/span&gt; y) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; x - y;&lt;br /&gt;
}
&lt;/div&gt;
&lt;p&gt;Это не правда. Во-первых, как поведёт себя такая функция сравнения с аргументами:&lt;/p&gt;
&lt;div class="code"&gt;
&lt;span class="kw"&gt;var&lt;/span&gt; compare = CompareTo(&lt;span class="t"&gt;Int32&lt;/span&gt;.MaxValue, &lt;span class="t"&gt;Int32&lt;/span&gt;.MinValue);
&lt;/div&gt;
&lt;p&gt;и, во-вторых (если это не убедительно), посмотрите, наконец, реализацию:&lt;/p&gt;
&lt;div class="code"&gt;
&lt;span class="kw"&gt;public int&lt;/span&gt; CompareTo(&lt;span class="kw"&gt;int&lt;/span&gt; value) { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="c"&gt;// Need to use compare because subtraction will wrap&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="c"&gt;// to positive for very large neg numbers, etc.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;if&lt;/span&gt; (m_value &lt; value) &lt;span class="kw"&gt;return&lt;/span&gt; -1;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;if&lt;/span&gt; (m_value &gt; value) &lt;span class="kw"&gt;return&lt;/span&gt; 1;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span class="kw"&gt;return&lt;/span&gt; 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-5454278855952303286?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/5454278855952303286/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/08/compareto.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/5454278855952303286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/5454278855952303286'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2011/08/compareto.html' title='О реализации сравнений /* CompareTo() */'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-7338033456273300460</id><published>2010-10-06T19:55:00.001+04:00</published><updated>2010-10-06T20:11:51.456+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BCL'/><title type='text'>System.DateTime: pro и contra</title><content type='html'>&lt;p&gt;
На РСДН развернулась &lt;a href="http://rsdn.ru/forum/philosophy/3984210.aspx"&gt;интересная дискуссия&lt;/a&gt; по поводу "косячности" &lt;span class="c"&gt;System.DateTime&lt;/span&gt;.

Насобирал ссылок по теме и о &lt;span class="c"&gt;DateTime&lt;/span&gt; вообще, пускай будут вместе.
&lt;/p&gt;

&lt;p&gt;
Кратко:
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/06/18/a-brief-history-of-datetime-anthony-moore.aspx"&gt;A Brief History of DateTime&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/07/12/a-brief-history-of-datetime-follow-up-anthony-moore.aspx"&gt;A Brief History of DateTime Follow-up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
Детали про &lt;span class="c"&gt;DateTime&lt;/span&gt;:
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2006/10/03/system.timezone2-starter-guide-_5b00_kathy-kam_5d00_.aspx"&gt;System.TimeZone2 Starter Guide&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free.aspx"&gt;Exploring Windows Time Zones with System.TimeZoneInfo&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/06/11/system-timezoneinfo-working-with-ambiguous-and-invalid-points-in-time-josh-free.aspx"&gt;System.TimeZoneInfo: Working with Ambiguous and Invalid Points in Time&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/06/12/datetime-touniversaltime-returns-maxvalue-minvalue-on-overflow-josh-free.aspx"&gt;BCL Refresher: DateTime.ToUniversalTime returns MaxValue/MinValue on overflow&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bclteam/archive/2007/06/14/datetimeoffset-a-new-datetime-structure-in-net-3-5-justin-van-patten.aspx"&gt;DateTimeOffset: A New DateTime Structure in .NET 3.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-7338033456273300460?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/7338033456273300460/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/10/systemdatetime-pro-contra.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7338033456273300460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7338033456273300460'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/10/systemdatetime-pro-contra.html' title='System.DateTime: pro и contra'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-1369684420946256040</id><published>2010-04-08T20:06:00.000+04:00</published><updated>2011-09-29T10:55:09.624+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><title type='text'>WPF, DataBinding и ToolTip</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;&lt;p&gt;WPF - интересная технология! Интересная, прежде всего, своими странностями и непонятностями, которые, вкупе с мощью и развесистостью библиотек, не перестают удивлять. :о)) В этот раз "порадовал" датабаиндинг внутри комплексного тултипа (всплывающей подсказки). Примитивнейший, казалось бы, пример:&lt;/p&gt;&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Window&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: purple;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;Class&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;WpfApplication2.Window1&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: purple;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span style="color: purple;"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span style="color: purple;"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;local&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;clr-namespace:WpfApplication2&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span style="color: purple;"&gt; Width&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Height&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDataProvider&lt;/span&gt;&lt;span style="color: purple;"&gt; x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;Key&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;MyData&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;//test:Items/test:Item&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDataProvider.XmlNamespaceManager&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlNamespaceMappingCollection&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlNamespaceMapping&lt;/span&gt;&lt;span style="color: purple;"&gt; Uri&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;urn:test&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Prefix&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlNamespaceMappingCollection&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDataProvider.XmlNamespaceManager&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XData&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Items&lt;/span&gt;&lt;span style="color: purple;"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;urn:test&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Item&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text 1&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Description&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Description 1&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Item&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text 2&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Description&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Description 2&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Item&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text 3&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Description&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Description 3&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Items&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XData&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;XmlDataProvider&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: purple;"&gt; x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;Key&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;MyTemplate&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Text'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: purple;"&gt; Orientation&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Text'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot; : &amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Description'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style="color: navy;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ItemsControl&lt;/span&gt;&lt;span style="color: purple;"&gt; ItemTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StaticResource&lt;/span&gt;&lt;span style="color: purple;"&gt; MyTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; ItemsSource&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; Source&lt;/span&gt;&lt;span style="color: blue;"&gt;={&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StaticResource&lt;/span&gt;&lt;span style="color: purple;"&gt; MyData&lt;/span&gt;&lt;span style="color: blue;"&gt;}}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Window&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;Но если включить вывод отладочной информации из источника System.Windows.Data (см. &lt;a href="http://blogs.msdn.com/mikehillberg/archive/2006/09/14/WpfTraceSources.aspx"&gt;Trace sources in WPF&lt;/a&gt; или недавний пост про &lt;a href="http://viacheslav-ivanov.blogspot.com/2010/03/presentationtracesources-wpf.html"&gt;Отключение PresentationTraceSources в WPF&lt;/a&gt;) то в окошке Output студии можно видеть:&lt;/p&gt;&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:XPath=@Description; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:XPath=@Text; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:XPath=@Description; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 40 : BindingExpression path error: 'InnerText' property not found for 'current item of collection' because data item is null.  This could happen because the data provider has not produced any data yet. BindingExpression:Path=/InnerText; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 19 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=/InnerText; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=/InnerText; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=/InnerText; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
System.Windows.Data Information: 40 : BindingExpression path error: 'InnerText' property not found for 'current item of collection' because data item is null.  This could happen because the data provider has not produced any data yet. BindingExpression:Path=/InnerText; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;Мне это кажется непорядком: а почему бы и не выполнить предписания и не сделать баиндинг только тогда, когда данные действительно появятся? При этом получилось вот что:&lt;/p&gt;&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: purple;"&gt; x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: purple;"&gt;Key&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;MyTemplate&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Text'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: purple;"&gt; Name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;ToolTip&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Orientation&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style&lt;/span&gt;&lt;span style="color: purple;"&gt; TargetType&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Type&lt;/span&gt;&lt;span style="color: purple;"&gt; TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Setter&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Text'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style.Triggers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Trigger&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;DataContext&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Null&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Setter&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Trigger&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style.Triggers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: purple;"&gt; Text&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot; : &amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style&lt;/span&gt;&lt;span style="color: purple;"&gt; TargetType&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Type&lt;/span&gt;&lt;span style="color: purple;"&gt; TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Setter&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: purple;"&gt; XPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;'&lt;/span&gt;@&lt;span style="color: navy;"&gt;Description'&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style.Triggers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Trigger&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;DataContext&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515;"&gt;x&lt;/span&gt;&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Null&lt;/span&gt;&lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Setter&lt;/span&gt;&lt;span style="color: purple;"&gt; Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color: purple;"&gt; Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: navy;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Trigger&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style.Triggers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.Style&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock.ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;То есть баиндинг выставляется через стиль, а затем в &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;DataTrigger&lt;/span&gt;-е сбрасывается в случае, когда данных нет.&lt;/p&gt;&lt;p&gt;Я ещё не до конца уверен, что подобными оптимизациями вообще стоит заниматься, но всё-таки лучше, когда удаётся обойти максимально возможное количество предупреждений. В данном случае обойти предупреждения совсем не тяжело, хотя и кода получилось заметно больше.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-1369684420946256040?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/1369684420946256040/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/04/wpf-databinding-tooltip.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/1369684420946256040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/1369684420946256040'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/04/wpf-databinding-tooltip.html' title='WPF, DataBinding и ToolTip'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-6977184424784278498</id><published>2010-04-02T11:08:00.003+04:00</published><updated>2010-04-02T11:16:20.382+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Сниппеты для проверки аргументов на null</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Думаю, есть время поделиться моими любимыми и наиболее часто используемыми сниппетами.&lt;/p&gt;
&lt;p&gt;Предназначены мои любимые сниппеты для такой прозаической задачи, как проверка аргументов на &lt;span style="font-family: Consolas, Courier, Monospace; color: blue;"&gt;null&lt;/span&gt;. Поскольку, с использованием сниппетов добавлять такие проверки стало гораздо быстрее и удобнее, не составляет труда добавлять проверки всюду, где в них есть необходимость, даже если сделать это нужно для нескольких параметров, а это позволяет писать более правильный, более безопасный код, ибо чем раньше мы обнаружим проблему, тем быстрее, проще и безопаснее для всего остального сможем её исправить.&lt;/p&gt;

&lt;p&gt;Не секрет, что для упрощения проверок аргументов на &lt;span style="font-family: Consolas, Courier, Monospace; color: blue;"&gt;null&lt;/span&gt; изобретено не мало средств: от &lt;a href="http://rsdn.ru/forum/dotnet/3617012.aspx"&gt;использования возможностей языка\компилятора&lt;/a&gt; до специальных инструментов a-la CodeContracts, аннотоций ReSharper-а или колдунства PostSharp-а.&lt;/p&gt;

&lt;p&gt;Мне всё это (пока что) кажется излишним оверхедом: тратить время на разбор выражений обидно, с контрактами &lt;a href="http://rsdn.ru/forum/jetbrains/3745671.aspx"&gt;действительно пока не всё понятно&lt;/a&gt;, завязываться же на инструмент третий стороны не хочется вовсе.&lt;/p&gt;

&lt;p&gt;Итак, как делаю я: написав объявление метода и операторные скобки к нему, обозначив тело:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: Blue"&gt;void&lt;/span&gt; MyMethod(&lt;span style="color: Blue"&gt;object&lt;/span&gt; param1, &lt;span style="color: Blue"&gt;object&lt;/span&gt; param2) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;| &lt;span style="color:Green"&gt;// &lt;- это позиция курсора в редакторе&lt;/span&gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip;набираю "&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an&lt;/span&gt;" (это shortcut для сниппета), жму &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;Tab&lt;/span&gt; и получаю:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;br /&gt;
  &lt;span style="color: Blue;"&gt;if&lt;/span&gt;(&lt;span style="border: 1px solid black; background-color: highlight; color: highlighttext"&gt;ArgName&lt;/span&gt; == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"&lt;span style="border:1px dotted gray;"&gt;ArgName&lt;/span&gt;"&lt;/span&gt;);&lt;br /&gt;
  }&lt;span style="color: Green"&gt;//if&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;

&lt;p&gt;Осталось ввести имя аргумента (курсор уже там, где нужно, в выделенном квадрате + помогает IntelliSense) и нажать &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;Enter&lt;/span&gt;:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: Blue"&gt;void&lt;/span&gt; MyMethod(&lt;span style="color: Blue"&gt;object&lt;/span&gt; param1, &lt;span style="color: Blue"&gt;object&lt;/span&gt; param2) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: Blue;"&gt;if&lt;/span&gt;(param1 == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"param1"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;}&lt;span style="color: Green"&gt;//if&lt;/span&gt;&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;|&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Можно приступать к написанию тела метода.&lt;/p&gt;

&lt;p&gt;Но если нужно проверить и второй параметр, то ставлю курсор перед закрывающей скобкой: &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;}&lt;span style="color: green"&gt;//if&lt;/span&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: Blue"&gt;void&lt;/span&gt; MyMethod(&lt;span style="color: Blue"&gt;object&lt;/span&gt; param1, &lt;span style="color: Blue"&gt;object&lt;/span&gt; param2) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: Blue;"&gt;if&lt;/span&gt;(param1 == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"param1"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;|}&lt;span style="color: Green"&gt;//if&lt;/span&gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;&amp;hellip;набираю "&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an2&lt;/span&gt;", жму &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;Tab&lt;/span&gt; и получаю:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: Blue"&gt;void&lt;/span&gt; MyMethod(&lt;span style="color: Blue"&gt;object&lt;/span&gt; param1, &lt;span style="color: Blue"&gt;object&lt;/span&gt; param2) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: Blue;"&gt;if&lt;/span&gt;(param1 == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"param1"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;} &lt;span style="color: Blue"&gt;else if&lt;/span&gt;(&lt;span style="border: 1px solid black; background-color: highlight; color: highlighttext"&gt;ArgName&lt;/span&gt; == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"&lt;span style="border:1px dotted gray;"&gt;ArgName&lt;/span&gt;"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;}&lt;span style="color: Green"&gt;//if&lt;/span&gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Опять быстро с помощью IntelliSense ввожу имя второго параметра, жму &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;Enter&lt;/span&gt;:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: Blue"&gt;void&lt;/span&gt; MyMethod(&lt;span style="color: Blue"&gt;object&lt;/span&gt; param1, &lt;span style="color: Blue"&gt;object&lt;/span&gt; param2) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: Blue;"&gt;if&lt;/span&gt;(param1 == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"param1"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;} &lt;span style="color: Blue"&gt;else if&lt;/span&gt;(param2 == &lt;span style="color: Blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue"&gt;throw new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: Navy;"&gt;"param2"&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;}&lt;span style="color: Green"&gt;//if&lt;/span&gt;&lt;br /&gt;
    &amp;nbsp;&amp;nbsp;|&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Вот так вот несколькими нажатиями я "набираю" довольно много нужного кода.&lt;/p&gt;
&lt;p&gt;В добавок к сниппетам "&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an&lt;/span&gt;" и "&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an2&lt;/span&gt;" у меня есть сниппеты ("&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;ans&lt;/span&gt;" и "&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;ans2&lt;/span&gt;" соответственно) для проверки строк, которые отличаются от первых тем, что вместо проверки на &lt;span style="font-family: Consolas, Courier, Monospace; color:Blue"&gt;null&lt;/span&gt; в условии выполняется проверка аргумента с помощью &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color:Blue"&gt;string&lt;/span&gt;)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Выглядит первый ("&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an&lt;/span&gt;") сниппет так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CodeSnippets&lt;/span&gt; &lt;span style="color: purple;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CodeSnippet&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Format&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;1.0.0&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Header&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Throws ArgumentNullException&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Title&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Shortcut&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;an&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Shortcut&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Code snippet for throws ArgumentNullException&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Description&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;SnippetTypes&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;SnippetType&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Expansion&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;SnippetType&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;SnippetTypes&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Author&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Viacheslav.Ivanov@GMail.com&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Author&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Header&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgumentName&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Name of the argument&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Default&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgName&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Default&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Editable&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgumentNullException&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;SimpleTypeName(global::System.ArgumentNullException)&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Type of the exception&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;CSharp&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;if($ArgumentName$ == null) {&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;throw new $ArgumentNullException$(&amp;quot;$ArgumentName$&amp;quot;);&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;}//if&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;$end$&lt;/span&gt;&lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CodeSnippet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CodeSnippets&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;

&lt;p&gt;Остальные сниппеты такие (привожу здесь только "значимую" часть, упустив заголовок):&lt;/p&gt;
&lt;p&gt;Проверка второго и последующих аргументов на &lt;span style="font-family: Consolas, Courier, Monospace; color: blue;"&gt;null&lt;/span&gt; ("&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;an2&lt;/span&gt;"):&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;CSharp&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;} else if($ArgumentName$ == null) {&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;throw new $ArgumentNullException$(&amp;quot;$ArgumentName$&amp;quot;);$end$&lt;/span&gt;&lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;

&lt;p&gt;Проверка строки на &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;IsNullOrEmpty&lt;/span&gt; ("&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;ans&lt;/span&gt;"):&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgumentName&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Name of the argument&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Default&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgName&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Default&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Editable&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;String&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;SimpleTypeName(global::System.String)&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;System.String type&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Editable&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;ArgumentNullException&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;SimpleTypeName(global::System.ArgumentNullException)&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Function&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Type of the exception&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ToolTip&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Literal&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Declarations&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;CSharp&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;if($String$.IsNullOrEmpty($ArgumentName$)) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: gray;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; throw new $ArgumentNullException$(&amp;quot;$ArgumentName$&amp;quot;);&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: gray;"&gt;&amp;nbsp; &amp;nbsp; }//if&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: gray;"&gt;&amp;nbsp; &amp;nbsp; $end$&lt;/span&gt;&lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Snippet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Проверка второго и последующий аргументов строкового типа на &lt;span style="font-family: Consolas, Courier, Monospace;"&gt;IsNullOrEmpty&lt;/span&gt; ("&lt;span style="font-family: Consolas, Courier, Monospace;"&gt;ans2&lt;/span&gt;"):&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier, Monospace; color: black; white-space: nowrap; overflow: auto;"&gt;
&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: navy;"&gt;CSharp&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;} else if($String$.IsNullOrEmpty($ArgumentName$)) {&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;throw new $ArgumentNullException$(&amp;quot;$ArgumentName$&amp;quot;);$end$&lt;/span&gt;&lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Скачать готовые сниппеты можно &lt;a href="http://files.rsdn.ru/7138/MyCustomSnippets.zip"&gt;отсюда&lt;/a&gt;. О том, как их подключить к MSVS можно прочитать в статье &lt;a href="http://msdn.microsoft.com/en-us/library/9ybhaktf.aspx"&gt;How to: Manage Code Snippets&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-6977184424784278498?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/6977184424784278498/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/04/null.html#comment-form' title='Комментарии: 10'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/6977184424784278498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/6977184424784278498'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/04/null.html' title='Сниппеты для проверки аргументов на null'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-937647110086344082</id><published>2010-03-11T18:43:00.000+03:00</published><updated>2010-03-11T18:43:13.669+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>Возрождение :о))</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Ура!&lt;/p&gt;
&lt;p&gt;Мне наконец-то удалось найти удобный способ написания сообщений в свой же блог, а это была единственная причина, останавливавшая меня от приступов графоманства :о) Мне удалось достаточно быстро немного переформатировтаь предыдущие посты (прошу прощение, если кому-то в rss помешали мои всплывшие сообщения) и шустро написать один новый.&lt;/p&gt;
&lt;p&gt;Надеюсь, полосы прокрутки для кода никому сильно не помешают, мне показалось что они удобнее, чем перенос строк.&lt;/p&gt;

&lt;p&gt;Если кто знает, как имеющийся у меня шаблон внешнего вида блога настроить так, что бы центральная панель с сообщениями была бы не фиксированного значения, а занимала бы всё доступное (по ширине) пространство - прошу помочь. Сильно хочу так сделать, но пока не получается. У кого-то случайно видел такой шаблон, но уже не могу вспомнить у кого именно :о(&lt;/p&gt;

&lt;p&gt;Кому интересно, то технология у меня простая - создаю в MSVS (2010) новую HTML страничку и в ней набираю то, что хочу опубликовать. Сложно было разобраться с переносами - наконец-то нашёл, где тут переключатели, позволяющие не реагировать текстовому процессору на обычный перевод строки и обращать внимание только на соответствующие явные средства HTML a-la &lt;span style="font-family: Consolas, Courier;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;br&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt; и &lt;span style="font-family: Consolas, Courier;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;p&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;. Есть один общий плюс к каждому посту свой собственный такой переключатель.&lt;/p&gt;

&lt;p&gt;Весь код и его раскраску набираю сам врукопашную же в том же текстовом редакторе студии. Оказывается, это совсем не сложно :о)) Xml набирать сложнее :о)) Ни одного достаточно удобного плагина к студии на эту тему отыскать не сумел.&lt;/p&gt;
&lt;p&gt;Зато выглядит теперь всё так, как мне нравится, а, значит, развивать сие будет интереснее.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-937647110086344082?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/937647110086344082/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/03/blog-post.html#comment-form' title='Комментарии: 9'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/937647110086344082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/937647110086344082'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/03/blog-post.html' title='Возрождение :о))'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-7805447377704742325</id><published>2010-03-11T18:19:00.000+03:00</published><updated>2010-03-11T18:19:04.966+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='Diagnostics'/><title type='text'>Отключение PresentationTraceSources в WPF</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Если вы когда-либо отлаживали WPF-приложение, то могли видеть в окошке Output отладчика примерно такой вывод:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black;"&gt;
  System.Windows.Data Error: 4 : Cannot find source for binding with reference &amp;hellip;&lt;br /&gt;
  System.Windows.Data Error: 39 : BindingExpression path error: &amp;hellip;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;и тому подобное. Это "работает" класс &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.aspx" style="font-family: Consolas, Courier;"&gt;PresentationTraceSources&lt;/a&gt;. Подробнее о нём можно узнать в статьях &lt;a href="http://blogs.msdn.com/mikehillberg/archive/2006/09/14/WpfTraceSources.aspx"&gt;Trace sources in WPF&lt;/a&gt; и &lt;a href="http://bea.stollnitz.com/blog/?p=52"&gt;How can I debug WPF bindings?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Я расскажу не о том, зачем нужен этот класс и не о том, как им пользоваться, а о том, как же его "отключить", то есть как добиться того, что бы в Output не писалось то, что вам, может быть, и не нужно.&lt;/p&gt;

&lt;p&gt;Самый простой способ отключения вывода &lt;span style="font-family: Consolas, Courier; color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt; - програмный:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt;&amp;gt; disable = traceSource =&gt; traceSource.Switch.Level = &lt;span style="color: #2b91af"&gt;SourceLevels&lt;/span&gt;.Off;&lt;br /&gt;
  disable(&lt;span style="color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt;.AnimationSource);&lt;br /&gt;
  disable(&lt;span style="color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt;.DataBindingSource);&lt;br /&gt;
  disable(&lt;span style="color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt;.DependencyPropertySource);&lt;br /&gt;
  &lt;span style="color: green"&gt;// &amp;hellip; И так далее по всем имеющимся TraceSource-ам&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Но этот способ и самый неинтересный, потому что его трудно поддерживать: необходимо изменить код (и, как следствие - перекомпилировать программу) что бы добавить, убрать или как-то более хитро настроить полезный зачастую вывод.&lt;/p&gt;

&lt;p&gt;Правильный путь: воспользоваться файлом конфигурации. Но и следующее решение не будет работать:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Data&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchValue&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;&lt;b&gt;Off&lt;/b&gt;&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;&amp;lt;!-- и так далее &amp;hellip; --&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;при запуске программы из-под отладчика, из-за того, что внутри &lt;span style="font-family: Consolas, Courier; color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt; при создании экземпляра &lt;span style="font-family: Consolas, Courier; color: #2b91af"&gt;TraceSource&lt;/span&gt; проверяется, не подключён ли отладчик, и если подключён, и для &lt;span style="font-family: Consolas, Courier; color: purple;"&gt;switchValue&lt;/span&gt; указано значение &lt;span style="font-family: Consolas, Courier; color: black"&gt;Off&lt;/span&gt;, то будет использоваться значение &lt;span style="font-family: Consolas, Courier; color: #2b91af"&gt;SourceLevels&lt;/span&gt;.&lt;span style="font-family: Consolas, Courier; color: black"&gt;Warning&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Зная вышесказанное, не сложно исхотриться так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Data&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchValue&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;&lt;b&gt;Critical&lt;/b&gt;&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: green;"&gt;&amp;lt;!-- и так далее &amp;hellip; --&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;где &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;Critical&lt;/span&gt; - самый строгий уровень вывода, но отличный от &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;Off&lt;/span&gt;. На практике ни одного сообщения с критическим уровнем важности я ещё не встечал, поэтому в ситуациях, когда хочется по возможности максимально избавиться от ненужного вывода, можно воспользоваться описанным советом.&lt;/p&gt;

&lt;p&gt;На последок, полный пример с небольшой универсализацией, позволяющей задавать уровень вывода &lt;span style="font-family: Consolas, Courier; color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt; один раз:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Data&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.DependencyProperty&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Documents&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Freezable&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Interop.HwndHost&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Markup&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.Media.Animation&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.NameScope&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.ResourceDictionary&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;source&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;System.Windows.RoutedEvent&lt;/span&gt;" &lt;span style="color: purple;"&gt;switchName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;&amp;lt;!-- Для 3.5 указано всё, что есть --&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sources&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;switches&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;&amp;lt;!-- Do not use an "Off", because under debugger it's replaced to "Warning". --&amp;gt;&lt;/span&gt;&lt;br /&gt;
      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;add&lt;/span&gt; &lt;span style="color: purple;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;PresentationTraceSwitch&lt;/span&gt;" &lt;span style="color: purple;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Critical&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;switches&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;И не забудьте где-либо в коде вашей программы вызвать&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: #2b91af"&gt;PresentationTraceSources&lt;/span&gt;.Refresh();&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;без вызова метода &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.refresh.aspx" style="font-family: Consolas, Courier;"&gt;Refresh()&lt;/a&gt; значения не будут зачитаны из конфигурационного файла.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-7805447377704742325?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/7805447377704742325/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/03/presentationtracesources-wpf.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7805447377704742325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7805447377704742325'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2010/03/presentationtracesources-wpf.html' title='Отключение PresentationTraceSources в WPF'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-7212838742452451000</id><published>2009-04-07T17:20:00.020+04:00</published><updated>2010-03-11T15:12:47.914+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='Guidelines'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>“Парные” методы</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Значение термина, вынесенного в заголовок, скорее всего никому кроме меня неизвестно. Это потому, что я сам его придумал, так как не знаю точного названия того, о чём хочу рассказать. А речь пойдёт о методах, которые обязательно должны быть вызваны вместе. Примерами таких служат &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.beginupdate.aspx"&gt;ListBox.BiginUpdate()&lt;/a&gt; и &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.endupdate.aspx"&gt;ListBox.EndUpdate()&lt;/a&gt; или &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.assert.aspx"&gt;CodeAccessPermission.Assert()&lt;/a&gt; и &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.revertassert.aspx"&gt;CodeAccessPermission.RevertAssert()&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Объединяет эти методы то, что вызвав первый из них (дальше я буду называть его Begin-вызовом) программист обязан (в случае, если вызов завершился успешно) вызвать и второй (я буду называть его End-вызов). Часто реализуют такие вызовы следующим образом:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  listBox.&lt;strong&gt;BeginUpdate()&lt;/strong&gt;; &lt;span style="color: green"&gt;// Begin-вызов&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue"&gt;try&lt;/span&gt; {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: green"&gt;// Некоторая полезная работа&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  } &lt;span style="color: blue"&gt;finally&lt;/span&gt; {&lt;br /&gt;
  &amp;nbsp; listBox.&lt;strong&gt;EndUpdate()&lt;/strong&gt;; &lt;span style="color: green"&gt;// End-вызов&lt;/span&gt;&lt;br /&gt;
  }&lt;span style="color: green"&gt;//try&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;то есть код после Begin-вызова заключают в блок &lt;font style="font-family: Consolas,Courier; color: blue"&gt;try&lt;/font&gt;, а End-вызов в &lt;font style="font-family: consolas, courier; color: blue"&gt;finally&lt;/font&gt;. Это позволяет (в скобках заметим, худо-бедно) гарантировать, что в случае возникновения исключения между вызовами объект, методы которого вызываются, останется в согласованном состоянии.&lt;/p&gt;
&lt;p&gt;Конечно, использовать &lt;font color="#0000ff" face="Consolas, courier"&gt;try&lt;/font&gt;-&lt;font color="#0000ff" face="Consolas, courier"&gt;finally&lt;/font&gt; каждый раз при одинаковых вызовах очень неудобно. О способе избежать такого неудобства я и расскажу.&lt;/p&gt;
&lt;p&gt;Обычно, для упрощения вызова “парных” методов, используют класс-хелпер, реализующий &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;IDisposable Interface&lt;/a&gt;, и вызывающий в своей реализации &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx"&gt;Dispose()&lt;/a&gt; End-метод:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;internal&lt;/span&gt; &lt;span style="color: blue"&gt;sealed&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxUpdateHelper&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox;&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; ListBoxUpdateHelper(&lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt;(listBox == &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: navy"&gt;&amp;quot;listBox&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span style="color: green"&gt;//if&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.listBox = listBox;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox.BeginUpdate();&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; ListBox {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af"&gt;DebuggerStepThrough&lt;/span&gt;]&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; listBox; }&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose() {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox.EndUpdate();&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Теперь вызывать BeginUpdate и EndUpdate удобнее:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;using&lt;/span&gt;(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxUpdateHelper&lt;/span&gt;(listBox)) {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: green"&gt;// Некоторая полезная работа&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  }&lt;span style="color: green"&gt;//using&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Мне он не нравится по той причине, что требует необходимости завести новую сущность – тип-хелпер и всюду в месте применения её использовать. Для пользователя библиотеки это может оказаться сложным: что бы легко и удобно пользоваться некоей функциональностью типа (ListBox в нашем примере) надо “позвать на помощь” другой тип. А если различных парных методов требуется несколько? Несколько и типов-хелперов.&lt;/p&gt;
&lt;p&gt;Поэтому прогрессивное сообщество пошло дальше, вместо типа-хелпера предоставив пользователю метод-хелпер:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;internal&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxExtensions&lt;/span&gt;&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt; DoUpdate(&lt;span style="color: blue"&gt;this&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxUpdateHelper&lt;/span&gt;(listBox);&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;sealed&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxUpdateHelper&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox;&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; ListBoxUpdateHelper(&lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt;(listBox == &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: navy"&gt;&amp;quot;listBox&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span style="color: green"&gt;//if&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.listBox = listBox;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox.BeginUpdate();&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; ListBox {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af"&gt;DebuggerStepThrough&lt;/span&gt;]&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; listBox; }&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose() {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox.EndUpdate();&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Который можно использовать так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;using&lt;/span&gt;(listBox.&lt;strong&gt;DoUpdate()&lt;/strong&gt;) {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: green"&gt;// Некоторая полезная работа&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  &amp;nbsp; listbox.Items.Add(&lt;span style="color: navy"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;);&lt;br /&gt;
  }&lt;span style="color: green"&gt;//using&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Теперь “снаружи” виден лишь один метод DoUpdate(), по типу возвращаемого значения которого (IDisposable) вызывающий будет знать, что метод, по возможности, лучше вызвать в блоке &lt;font style="font-family: consolas, courier; color: blue"&gt;using&lt;/font&gt;.&lt;/p&gt;
&lt;p&gt;Указанный подход можно найти в большом количестве библиотек, например в &lt;a href="http://rsat.codeplex.com/SourceControl/changeset/view/29215#395976"&gt;R Smart Application Toolkit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Но меня не устраивает и этот вариант. Вернее, громозкозть его реализации. Спустя какое-то время увлечения данной методикой мне надоело писать большое количество классов-хелперов (которые по прежнему остались в виде &lt;font style="font-family: consolas, courier; color: blue"&gt;private&lt;/font&gt;) и я начал пользоваться таким вот классом:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Disposable&lt;/span&gt;&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt; New(&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; dispose) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionDisposable&lt;/span&gt;(dispose);&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp; [&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;
  &amp;nbsp; [&lt;span style="color: #2b91af"&gt;DebuggerDisplay&lt;/span&gt;(&lt;span style="color: navy"&gt;&amp;quot;{ Action != null ? \&amp;quot;&amp;lt;Action&amp;gt;\&amp;quot; : \&amp;quot;&amp;lt;Action (Empty)&amp;gt;\&amp;quot; }&amp;quot;&lt;/span&gt;)]&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;sealed&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionDisposable&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; ActionDisposable(&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; action) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action = action;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt; Action { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt;
  &amp;nbsp;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose() {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt;(Action != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action();&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;span style="color: green"&gt;//if&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;С ним упростилось написание методов, аналогичных вышеприведённому DoUpdate():&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue"&gt;internal&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBoxExtensions&lt;/span&gt;&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDisposable&lt;/span&gt; DoUpdate(&lt;span style="color: blue"&gt;this&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ListBox&lt;/span&gt; listBox) {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; listBox.BeginUpdate();&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Disposable&lt;/span&gt;.New(listBox.EndUpdate);&lt;br /&gt;
  &amp;nbsp; }&lt;br /&gt;
  }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Что позволяет быстрее и проще, а, значит, и чаще использовать описанный паттерн (не побоюсь этого слова :о) – а кстати, как его можно назвать?).&lt;/p&gt;
&lt;p&gt;Подробнее о классе &lt;font style="font-family: consolas, courier; color: #2b91af"&gt;Disposable&lt;/font&gt; и ещё об одном обнаруженном с его помощью “паттерне” я раскажу как-нибудь в следующий раз.&lt;/p&gt;
&lt;p&gt;P.S. Касательно “худо-бедно”: существует возможность того, что поток, в котором выполняется рассматриваемый нами код, будет прерван вызовом &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx"&gt;Thread.Abort(…)&lt;/a&gt; из другого потока сразу после вызова Begin-метода и перед тем, как начнётся &lt;font style="font-family: consolas, courier; color: #0000ff"&gt;try&lt;/font&gt;-блок. Источник: &lt;a title="Fabulous Adventures In Coding: Eric Lippert&amp;#39;s Blog" href="http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx"&gt;Locks and exceptions do not mix&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-7212838742452451000?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/7212838742452451000/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2009/04/blog-post.html#comment-form' title='Комментарии: 7'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7212838742452451000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/7212838742452451000'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2009/04/blog-post.html' title='“Парные” методы'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-2224368759944037500</id><published>2008-10-21T23:00:00.003+04:00</published><updated>2010-03-11T15:16:20.976+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>#endregion-ы</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Самая необычная  конструкция в C#, по моему мнению, это деректива &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#region&lt;/span&gt;. Удивительно в ней то, что введена она в язык исключительно ради более удобной работы с исходным кодом. Компилятор, говоря языком стандарта, не налагает никакой семантики на "содержимое" региона.&lt;/p&gt;
&lt;p&gt;Служат регионы для возможности отделения блока кода внутри региона от остального кода по-соседству.&lt;/p&gt;
&lt;p&gt;Используютя регионы, зачастую, именно так, как показано в примере из MSDN:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: green;"&gt;// preprocessor_region.cs&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;#region&lt;/span&gt; MyClass definition&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; MyClass&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="color: blue;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;то есть начинаются как:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;#region&lt;/span&gt; Какое-либо описание ("заголовок")&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;а заканчиваются:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;чему во многом этому способствует "стандартный" сниппет (находящийся в "Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\pp_region.snippet"), позволяющий в несколько нажатий  клавиш вставить в редактор блок &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#region&lt;/span&gt; … &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#endregion&lt;/span&gt; и ввести лишь "заголовок".&lt;/p&gt;
&lt;p&gt;Директива &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#endregion&lt;/span&gt;, кажется, нужна лишь для того, что бы обозначить окончание региона и больше проку от неё нет. Но … это только на первый взгляд :о) она так же, как и &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#region&lt;/span&gt; может содержать информативное текстовое описание, а, значит, подсказывать, что же за код находится выше неё в редакторе и, часто, это очень полезно если "размер" региона больше одного экрана или просто не хочется высоко поднимать глаза, что бы увидеть, что же написано в заголовке региона. Главное, получить это можно практически бесплатно, если для вставки регионов вы пользуетесь code-snippets. Достаточно открыть в редакторе (хоть в той же MSVS) указанный выше файл pp_region.snippet и заменить&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt; &lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;csharp&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;#region $name$&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&lt;span style="color: gray;"&gt;$selected$$end$&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: gray;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;на&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt; &lt;span style="color: purple;"&gt;Language&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;csharp&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span style="color: gray;"&gt;#region $name$&lt;/span&gt;&lt;br /&gt;
  &amp;nbsp;&lt;span style="color: gray;"&gt;$selected$$end$&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: gray;"&gt;#endregion &lt;b&gt;$name$&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;]]&amp;gt;&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Code&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Теперь у вас будут более информативные и даже более стройные регионы:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: green;"&gt;// preprocessor_region.cs&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;#region&lt;/span&gt; MyClass definition&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; MyClass&lt;br /&gt;
  {&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
  &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="color: blue;"&gt;#endregion&lt;/span&gt; MyClass definition&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Не забывайте: человек может читать или просто просматривать код не только "сверху вниз", но и "снизу вверх", и в таком случае указанный у &lt;span style="font-family: Consolas, Courier; color: blue;"&gt;#endregion&lt;/span&gt; коментарий послужит на пользу.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-2224368759944037500?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/2224368759944037500/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2008/10/endregion.html#comment-form' title='Комментарии: 11'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/2224368759944037500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/2224368759944037500'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2008/10/endregion.html' title='#endregion-ы'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3365658765336324348.post-4468759943976429014</id><published>2008-10-08T22:12:00.004+04:00</published><updated>2010-03-11T15:24:48.189+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Guidelines'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Специализация типа для null</title><content type='html'>&lt;div style="font-family:Verdana;"&gt;
&lt;p&gt;Как известно, литерал "&lt;span style="font-family:Consolas,Courier; color:blue;"&gt;null&lt;/span&gt;" в C# может быть неявно преобразован в ссылочный или nullable - тип. В &lt;b&gt;любой&lt;/b&gt; ссылочный. Что, порой доставляет неудобства: допустим, у нас есть пара методов:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color:blue;"&gt;void&lt;/span&gt; Add(&lt;span style="color:blue;"&gt;string&lt;/span&gt; text) { &lt;span style="color:green;"&gt;/* … */&lt;/span&gt; }&lt;br /&gt;
  &lt;span style="color:blue;"&gt;void&lt;/span&gt; Add(&lt;span style="color: rgb(43, 145, 175);"&gt;Control&lt;/span&gt; content) { &lt;span style="color:green;"&gt;/* … */&lt;/span&gt; }&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;и нам необходимо вызвать первый из них, передав в него значение &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;null&lt;/span&gt;:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  Add(&lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Так как &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;null&lt;/span&gt; здесь может совершенно равноправно быть преобразован и в &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;string&lt;/span&gt; и в &lt;span style="font-family:Consolas,Courier; color:rgb(43, 145, 175);"&gt;Control&lt;/span&gt;, подобный вызов приведёт к ошибке компиляции:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black;"&gt;
  error CS0121: The call is ambiguous between the following methods or properties: '…Add(string)' and '…Add(…Control)'&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Избавляются от такой ошибки, помогая компилятору выбрать нужный метод, чаще всего таким вот образом:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  Add(&lt;b&gt;(&lt;span style="color:blue;"&gt;string&lt;/span&gt;)&lt;/b&gt;&lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;то есть используя тот же синтаксис, какой используется для приведения типа.&lt;/p&gt;
&lt;p&gt;Приведение типа - операция, происходящая во время выполнения программы и может закончится возникновением исключительной ситуации, поэтому к приведению типов многие програмисты относятся осторожно.&lt;/p&gt;
&lt;p&gt;А вот "приведение" &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;null&lt;/span&gt; к какому-либо типу в худшем случае закончится ошибкой компиляции и не требует такого осторожного обращения. Некоторым даже кажется недостатком языка то, что различные операции изменения типа (результат которых может или не может быть проверен компилятором) синтаксически выглядят одинаково (вспомним &lt;a href="http://msdn.microsoft.com/en-us/library/5f6c9f8h.aspx"&gt;Casting Operators&lt;/a&gt; из C++).&lt;/p&gt;
&lt;p&gt;К радости таких вот педантов (к которым я и себя отношу), в C# версии 2.0 появилось&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="font-family:Times New Roman; font-style:italic;"&gt;default-value-expression:&lt;/span&gt;&lt;br /&gt;
  &lt;span style="color:blue;"&gt;default&lt;/span&gt; (type)&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;"Соль" данного выражения в том, что во время выполнения оно имеет значение &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;null&lt;/span&gt; (для reference-типа), а его тип именно тот, что указан. С помощью &lt;i&gt;default-value-expression&lt;/i&gt; вызов метода можно переписать так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  Add(&lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;string&lt;/span&gt;));&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Результат мы достигли тот же самый, но без использования синтаксиса, похожего на операцию приведения типа.&lt;/p&gt;
&lt;p&gt;Так же, &lt;i&gt;default-value-expression&lt;/i&gt; поможет нам и в такой ситуации:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;int&lt;/span&gt;? x = flag ? 10 : &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="white-space:normal;"&gt;error CS0173: Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and '&amp;lt;null&amp;gt;'&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Компилятор не может вывести тип выражения после оператора присваивания если ему (компилятору) не помочь так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; x = flag ? 10 : &lt;b&gt;(&lt;span style="color: blue;"&gt;int&lt;/span&gt;?)&lt;span style="color: blue;"&gt;null&lt;/span&gt;&lt;/b&gt;;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;так&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; x = flag ? 10 : &lt;b&gt;&lt;span style="color: blue;"&gt;new int&lt;/span&gt;?()&lt;/b&gt;;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;или так:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; x = flag ? 10 : &lt;b&gt;&lt;span style="color: blue;"&gt;default&lt;/span&gt;(&lt;span style="color: blue;"&gt;int&lt;/span&gt;?)&lt;/b&gt;;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Несмотря на то, что последний вариант самый длинный из предложенных, мне он нравится больше всего, ибо и приведение типа, и создание экземпляра объекта синтаксически &lt;i&gt;выглядят как&lt;/i&gt; выполнение какой-то операции, хотя на самом деле в данном месте достаточно типизированного константного выражения.&lt;/p&gt;
&lt;p&gt;И ещё одно место, где использование &lt;i&gt;default-value-expression&lt;/i&gt; мне кажется оправданным: объявление и инициализация значением по-умолчанию локальных переменных. Например, мне кажется нелогичным, что в таком вот примере:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; my_integer = 0;&lt;br /&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; my_string = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;
  &lt;br /&gt;
  &lt;span style="white-space:normal;"&gt;error CS0815: Cannot assign &amp;lt;null&amp;gt; to an implicitly-typed local variable&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;в первом объявлении мы можем использовать &lt;span style="font-family:Consolas,Courier; color:blue;"&gt;var&lt;/span&gt;, а во-втором нет и нам приходится явно указывать тип переменной:&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; my_integer = 0;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&lt;/b&gt; my_string = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Куда как однообразнее выглядит&lt;/p&gt;
&lt;div style="font-family: Consolas, Courier; color: black; white-space: nowrap; overflow: auto;"&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; my_integer = 0;&lt;br /&gt;
  &lt;span style="color: blue;"&gt;var&lt;/span&gt; my_string = &lt;b&gt;&lt;span style="color: blue;"&gt;default&lt;/span&gt;(&lt;span style="color: blue;"&gt;string&lt;/span&gt;)&lt;/b&gt;;&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;Вот, пока что, и всё о простом, но интересном и полезном, на мой взгляд, средстве языка C#. Надеюсь, этот блог будет жить более активной жизнью, чем мой предыдущий на gotdotnet :о) Редактирование тут кажется более удобным (что является основным стопором), хотя LiveWriter мне прикрутить пока не удалось.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3365658765336324348-4468759943976429014?l=viacheslav-ivanov.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://viacheslav-ivanov.blogspot.com/feeds/4468759943976429014/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2008/10/null.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/4468759943976429014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3365658765336324348/posts/default/4468759943976429014'/><link rel='alternate' type='text/html' href='http://viacheslav-ivanov.blogspot.com/2008/10/null.html' title='Специализация типа для null'/><author><name>Viacheslav Ivanov</name><uri>https://profiles.google.com/116498199741158326056</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_YsAneiUdg/AAAAAAAAAAI/AAAAAAAAALs/PI2rGC9q17k/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry></feed>
