<?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-4177053433240488765</id><updated>2012-01-20T11:49:43.730-08:00</updated><category term='security https'/><category term='covariance tutorial'/><category term='Scala tutorial'/><category term='svn video tutorial'/><category term='sharpdevelop GSoC'/><category term='c# custom format double'/><category term='scala scripting'/><category term='C# delegates implemented outer-variables'/><category term='C# delegates events'/><category term='taskconnect outlook'/><category term='tfs outlook addin plugin'/><title type='text'>Coding time - Martin Konicek</title><subtitle type='html'>Programming and .NET</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-5171695135244490109</id><published>2011-07-03T04:10:00.000-07:00</published><updated>2011-07-03T04:17:00.280-07:00</updated><title type='text'>How to implement rule engine in C#</title><content type='html'>&lt;div class="WordSection1"&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;Recently there was an interesting &lt;a href="http://stackoverflow.com/questions/6488034/how-to-implement-a-rule-engine"&gt;question on StackOverflow&lt;/a&gt; about creating a rule engine in C#.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;Say we have a collection of Users (with Name, Age, ...) and rule definitions like this:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="background: white; line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;static&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;List&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;gt;&amp;nbsp;rules&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;List&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;gt;&amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"Age"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"GreaterThan"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"20"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;),&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="background: white; line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"Name"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"Equal"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"John"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: black;"&gt;),&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 10pt;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;(&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"Tags"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"Contains"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 10pt;"&gt;"C#"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black; font-family: Consolas; font-size: 10pt;"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="background: white; line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;and we want to be able to evaluate the rules:&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;//&amp;nbsp;Returns&amp;nbsp;true&amp;nbsp;if&amp;nbsp;User&amp;nbsp;satisfies&amp;nbsp;given&amp;nbsp;rule&amp;nbsp;(e.g.&amp;nbsp;'user.Age&amp;nbsp;&amp;gt;&amp;nbsp;20')&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;Matches(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;user,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;rule)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    &lt;/span&gt;&lt;span style="color: green; font-family: Consolas;"&gt;//&amp;nbsp;how&amp;nbsp;to&amp;nbsp;implement&amp;nbsp;this?&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="MsoNormal"&gt;One&amp;nbsp; obvious solution is to use reflection.&lt;br /&gt;Here we will show a solution which uses &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;Expression trees&lt;/a&gt; to&lt;br /&gt;&lt;b&gt;compile the rules into fast executable delegates&lt;/b&gt;. We can then evaluate the rules as if they were normal boolean functions.&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;public&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;static&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Func&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;lt;T,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;&amp;nbsp;CompileRule&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;r)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;paramUser&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Parameter(&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;typeof&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;));&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;    Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;expr&amp;nbsp;=&amp;nbsp;BuildExpr&amp;lt;T&amp;gt;(r,&amp;nbsp;paramUser);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;    //&amp;nbsp;build&amp;nbsp;a&amp;nbsp;lambda&amp;nbsp;function&amp;nbsp;User-&amp;gt;bool&amp;nbsp;and&amp;nbsp;compile&amp;nbsp;it&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;    return&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Lambda&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Func&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;lt;T,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;&amp;gt;(expr,&amp;nbsp;paramUser).Compile();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;static&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;BuildExpr&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;r,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;ParameterExpression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;param)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;    var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;left&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;MemberExpression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Property(param,&amp;nbsp;r.MemberName);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;    var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;tProp&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;typeof&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;(T).GetProperty(r.MemberName).PropertyType;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;    ExpressionType&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;tBinary;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;    //&amp;nbsp;is&amp;nbsp;the&amp;nbsp;operator&amp;nbsp;a&amp;nbsp;known&amp;nbsp;.NET&amp;nbsp;operator?&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;    if&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;ExpressionType&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.TryParse(r.Operator,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;out&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;tBinary))    {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;        var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;right&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Constant(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Convert&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.ChangeType(r.TargetValue,&amp;nbsp;tProp));&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;        &lt;/span&gt;&lt;span style="color: green; font-family: Consolas;"&gt;//&amp;nbsp;use&amp;nbsp;a&amp;nbsp;binary&amp;nbsp;operation,&amp;nbsp;e.g.&amp;nbsp;'Equal'&amp;nbsp;-&amp;gt;&amp;nbsp;'u.Age&amp;nbsp;==&amp;nbsp;15'&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;        return&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.MakeBinary(tBinary,&amp;nbsp;left,&amp;nbsp;right);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    } &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;else &lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;        var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;method&amp;nbsp;=&amp;nbsp;tProp.GetMethod(r.Operator);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;        var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;tParam&amp;nbsp;=&amp;nbsp;method.GetParameters()[0].ParameterType;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;        var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;right&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Constant(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Convert&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.ChangeType(r.TargetValue,&amp;nbsp;tParam));&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;        &lt;/span&gt;&lt;span style="color: green; font-family: Consolas;"&gt;//&amp;nbsp;use&amp;nbsp;a&amp;nbsp;method&amp;nbsp;call,&amp;nbsp;e.g.&amp;nbsp;'Contains'&amp;nbsp;-&amp;gt;&amp;nbsp;'u.Tags.Contains(some_tag)'&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;        &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;return&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Expression&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;.Call(left,&amp;nbsp;method,&amp;nbsp;right);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="MsoNormal"&gt;Now we can implement the rule validation by compling the rules and then simply invoking them:&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;var&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;rule&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Rule&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"Age"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"GreaterThan"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"20"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Func&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;&amp;nbsp;compiledRule&amp;nbsp;=&amp;nbsp;CompileRule&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;(rule);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;//&amp;nbsp;true&amp;nbsp;if&amp;nbsp;someUser.Age &amp;gt; 20&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;isMatch&amp;nbsp;=&amp;nbsp;compiledRule(someUser);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;Of course we compile all the rules just once and then use the compiled delegates:&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;// Compile all the rules once.&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;compiledRules&amp;nbsp;=&amp;nbsp;rules.Select(r&amp;nbsp;=&amp;gt;&amp;nbsp;CompileRule&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;(r)).ToList();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: green; font-family: Consolas;"&gt;// Returns true if user satisfies all rules.&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;public&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;bool&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;MatchesAllRules(&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;User&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;user)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;return&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;compiledRules.All(rule&amp;nbsp;=&amp;gt;&amp;nbsp;rule(user));&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="MsoNormal"&gt;Note that the &lt;span lang="EN-US"&gt;“compiler” &lt;/span&gt;is so simple because we are using 'GreaterThan' in the rule definition, and 'GreaterThan' is a known .NET name for the operator, so the string can be directly parsed. The same goes for 'Contains' – it is a method of List. If we need custom names we can build a very simple dictionary that just translates all operators before compiling the rules:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Dictionary&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;string&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;string&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;&amp;nbsp;nameMap&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;new&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Dictionary&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;string&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;string&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;gt;&amp;nbsp;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    {&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"greater_than"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"GreaterThan"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;    {&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"hasAtLeastOne"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas;"&gt;"Contains"&lt;/span&gt;&lt;span style="color: black; font-family: Consolas;"&gt;&amp;nbsp;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: white;"&gt;&lt;span style="color: black; font-family: Consolas;"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;That’s it. As an improvement we could add error messages to the rule definitions and print the error messages for the unsatisfied rules.&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;If you found this useful, feel free to &lt;a href="http://stackoverflow.com/questions/6488034/how-to-implement-a-rule-engine#answer-6560284"&gt;rate the answer on StackOverflow&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-5171695135244490109?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/5171695135244490109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2011/07/how-to-implement-rule-engine-in-c.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5171695135244490109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5171695135244490109'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2011/07/how-to-implement-rule-engine-in-c.html' title='How to implement rule engine in C#'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-6445208020942374185</id><published>2011-05-17T14:39:00.000-07:00</published><updated>2011-05-17T16:53:18.522-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='covariance tutorial'/><title type='text'>Covariance and contravariance - simple explanation</title><content type='html'>I tried to be as concise as possible. In 10 minutes you should understand what&lt;br /&gt;covariance/contravariance is and how to take advantage of it. The examples are in Scala.&lt;br /&gt;&lt;h3&gt;Covariance&lt;/h3&gt;Covariance lets you treat say List[Apple] as List[&lt;span style="border-bottom: 1px dotted" title="Apple is subclass of Fruit"&gt;Fruit&lt;/span&gt;].&lt;br /&gt;&lt;style&gt; /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin-top:0cm; mso-para-margin-right:0cm; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0cm; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-fareast-language:EN-US;}&lt;/style&gt;   &lt;br /&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;val&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; apples = List(&lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple(), &lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple())&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;processList(apples)&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;def &lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;processList(list:List[Fruit]) = {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #3f7f5f; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;// read the list&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;This seems obvious - indeed, a list of apples is a list of fruit, right?&lt;br /&gt;&lt;br /&gt;The surprise comes when we find out this does not work for arrays. Why is that so? Because you could do the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;val&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; a = Array(&lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple(), &lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple())&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;processArray(a)&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; processArray(array:Array[Fruit]) = {&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&amp;nbsp; array(1) = &lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Orange() &lt;/span&gt;&lt;span style="color: #3f7f5f; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;// putting an Orange into array of Apples!&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;The main difference between List and Array here is that the List is immutable (you cannot change its contents) while the Array is mutable. As long as we are dealing with immutable types, everything is OK (as in the first example).&lt;br /&gt;&lt;br /&gt;So how does the compiler know that List is immutable? Here is the declaration of List:&lt;br /&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;sealed abstract class&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; List[+A]&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;The +A type parameter says "List is covariant in A". That means the compiler &lt;span style="border-bottom: 1px dotted" title="by checking that List does have any methods that take A as parameter"&gt;checks&lt;/span&gt; that there is no way to change contents of the List, which eliminates the problem we had with arrays.&lt;br /&gt;&lt;br /&gt;Simply put, a covariant class is a class from which you can read stuff out, but you can't put stuff in.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Contravariance&lt;/h3&gt;Now when you already understand covariance, contravariance will be easier - it is exactly the opposite in every sense.&lt;br /&gt;&lt;br /&gt;You can put stuff in a contravariant class, but you can never get it out (imagine a &lt;span style="color: black;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;"&gt;Logger[-A]&lt;/span&gt;&lt;/span&gt; - you put stuff in to be logged). That doesn't sound useful, but there is one very useful application: functions. Say you've got a function taking Fruit:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #3f7f5f; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;// isGoodFruit is a func of type Fruit=&amp;gt;Boolean&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;"&gt;def&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;"&gt; isGoodFruit(f:Fruit) = f.ageDays &amp;lt; 3&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;and filter a list of Apples using this function:&lt;br /&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;val&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; list:List[Apple] = List(&lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple(), &lt;/span&gt;&lt;b&gt;&lt;span style="color: #7f0055; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;new&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Apple()) &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%;"&gt;list.filter(isGoodFruit) &lt;/span&gt;&lt;span style="color: #3f7f5f; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;// filter takes a func Apple=&amp;gt;Boolean &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;So a function of Fruits can be treated as function of Apples - the filter will throw Apples in and isGoodFruit will know how to handle them.&lt;br /&gt;&lt;br /&gt;The type of isGoodFruit is actually &lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;Function[Fruit, Boolean]&lt;/span&gt; - yes, in Scala even functions are &lt;span style="border-bottom: 1px dotted;" title="traits are similar to interfaces, but can contain method implementations"&gt;traits&lt;/span&gt;, declared as:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;trait Function[-A,+B]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So functions are &lt;span style="border-bottom: 1px dotted;" title="you can put superclasses of A in"&gt;contravariant in their parameter types&lt;/span&gt; and &lt;span style="border-bottom: 1px dotted;" title="you may get subclasses of B out"&gt;covariant in their return types&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;OK, that's it; this is the minimal explanation I wanted to cover. &lt;br /&gt;&lt;br /&gt;Did you find this understandable? Please provide feedback so I can make things even clearer. Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-6445208020942374185?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/6445208020942374185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2011/05/covariance-and-contravariance-simple.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6445208020942374185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6445208020942374185'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2011/05/covariance-and-contravariance-simple.html' title='Covariance and contravariance - simple explanation'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-4271802097557662897</id><published>2011-05-05T05:00:00.000-07:00</published><updated>2011-06-15T09:25:41.730-07:00</updated><title type='text'>Software engineering radio - best episodes</title><content type='html'>&lt;a href="http://www.se-radio.net/"&gt;Software engineering radio&lt;/a&gt; is an excellent podcast full of in-depth information for developers; contains high quality content different from what you usually find online.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;General&lt;/h4&gt;&lt;a href="http://www.se-radio.net/2010/07/episode-165-nosql-and-mongodb-with-dwight-merriman/"&gt;NoSQL and MongoDB with Dwight Merriman&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.se-radio.net/2009/04/episode-132-top-10-architecture-mistakes-with-eoin-woods/"&gt;Top 10 Architecture Mistakes with Eoin Woods&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.se-radio.net/2010/10/episode-168-being-a-consultant/"&gt;Being a consultant&lt;/a&gt;&amp;nbsp;- honest, informal and funny&lt;br /&gt;&lt;a href="http://www.se-radio.net/2009/11/episode-150-software-craftsmanship-with-bob-martin/"&gt;Software Craftsmanship with Bob Martin&lt;/a&gt; - concentrated motivation&lt;br /&gt;&lt;a href="http://www.se-radio.net/2008/05/episode-98-stefan-tilkov-on-rest/"&gt;Stefan Tilkov on REST&lt;/a&gt; - quite practical&lt;br /&gt;&lt;a href="http://www.se-radio.net/2008/03/episode-88-the-singularity-research-os-with-galen-hunt/"&gt;Singularity research OS&lt;/a&gt; - microkernels, safety, static code analysis&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Scala&lt;/h4&gt;&lt;a href="http://www.se-radio.net/2007/07/episode-62-martin-odersky-on-scala/"&gt;Martin Odersky on Scala&lt;/a&gt;&amp;nbsp;- great interview with the author of Scala&lt;br /&gt;&lt;a href="http://www.se-radio.net/2011/02/episode-171-scala-update-with-martin-odersky/"&gt;Scala Update with Martin Odersky&lt;/a&gt;&amp;nbsp;- second half provides insights into possible future of programming&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;OmegaTau&lt;/h4&gt;&lt;br /&gt;Btw, Markus Völter (the guy behind se-radio) also does a &lt;a href="http://omegataupodcast.net/category/podcast-en/"&gt;podcast&lt;/a&gt; on technology and science. Software engineer talking to a Nuclear fusion expert - what could we want more? ;) I really enjoyed the following episodes:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://omegataupodcast.net/2009/09/18-astrobiology-at-the-nasa-astrobiology-institute/"&gt;Astrobiology at the NASA Astrobiology Institute&lt;/a&gt;&lt;br /&gt;&lt;a href="http://omegataupodcast.net/2011/01/54-quantum-computing/"&gt;Quantum computing&lt;/a&gt; - kudos for mentioning the "next technical revolution"&lt;br /&gt;&lt;a href="http://omegataupodcast.net/2009/12/22-nuclear-fusion-at-mpi-fur-plasmaphysik/"&gt;Nuclear Fusion at MPI für Plasmaphysik&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;/h4&gt;Please help me find great episodes - if you know about an episode that you really enjoyed, post it into comments. Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-4271802097557662897?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/4271802097557662897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2011/05/software-engineering-radio-best.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/4271802097557662897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/4271802097557662897'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2011/05/software-engineering-radio-best.html' title='Software engineering radio - best episodes'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-464649104689529509</id><published>2011-02-06T15:08:00.000-08:00</published><updated>2011-02-06T15:08:13.996-08:00</updated><title type='text'>TFS addin for Outlook TaskConnect released!</title><content type='html'>&lt;a href="http://taskconnect.com/"&gt;TaskConnect &lt;/a&gt; connects Outlook with issue tracking systems in a very cool way. So far there is support for TFS (2008, 2010) and Redmine.&lt;br /&gt;&lt;br /&gt;This is how TaskConect looks inside Outlook:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.taskconnect.com/files/htmlpages/res/img/panel-outlook-example.png" /&gt;&lt;br /&gt;&lt;br /&gt;It has many useful concepts making you deal with your tasks in no time. Be sure to check out &lt;a href="http://taskconnect.com/"&gt;the entirely new website&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-464649104689529509?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/464649104689529509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2011/02/tfs-addin-for-outlook-taskconnect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/464649104689529509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/464649104689529509'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2011/02/tfs-addin-for-outlook-taskconnect.html' title='TFS addin for Outlook TaskConnect released!'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-686448243596346096</id><published>2011-01-21T07:02:00.000-08:00</published><updated>2011-05-05T04:04:12.692-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala scripting'/><title type='text'>Scripting in Scala</title><content type='html'>Imagine we have a long text file, for example:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(243, 245, 255); border: 1px solid gray; color: black; padding: 0.5em;"&gt;'CHINESE' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'zh'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;'DUTCH'&lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'nl'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;  &lt;br /&gt;'ENGLISH' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'en'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;'SPANISH' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'es'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And we want to turn it into this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(243, 245, 255); border: 1px solid gray; color: black; padding: 0.5em;"&gt;'zh' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'Chinese'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;'nl' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'Dutch'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;  &lt;br /&gt;'en' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'English'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;'es' &lt;span style="color: #808030;"&gt;:&lt;/span&gt; 'Spanish'&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What we want to do is very simple: "Swap the two parts on every line!", and I believe it should be this simple also in code. Let's see how it looks in Scala:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(243, 245, 255); border: 1px solid gray; color: black; padding: 0.5em;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; scala&lt;span style="color: #808030;"&gt;.&lt;/span&gt;io&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Source&lt;br /&gt;&lt;br /&gt;val lineRegex &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0f69ff;"&gt;\\&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;s+'(.+)'.*'(.+)'.*&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;r&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;line &lt;span style="color: #808030;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;-&lt;/span&gt; Source&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #603000;"&gt;stdin&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;getLines&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;   val lineRegex&lt;span style="color: #808030;"&gt;(&lt;/span&gt;name&lt;span style="color: #808030;"&gt;,&lt;/span&gt; code&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt; line&lt;br /&gt;   println&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;'&lt;/span&gt;&lt;span style="color: #0f69ff;"&gt;%s&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;': '&lt;/span&gt;&lt;span style="color: #0f69ff;"&gt;%s&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;',&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; format&lt;span style="color: #808030;"&gt; (&lt;/span&gt;code&lt;span style="color: #808030;"&gt;,&lt;/span&gt; name.toLowerCase.capitalize&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's 5 lines including the import, and the code is readable. Now we can run:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(243, 245, 255); border: 1px solid gray; color: black; padding: 0.5em;"&gt;cat languages.txt | scala ourScript.scala &amp;gt; output.txt&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's it.&lt;br /&gt;&lt;br /&gt;Btw, let's look at at the options we had for solving the problem:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We don't want to be writing code in Java, C++ or C# and actually &lt;i&gt;compiling an executable&lt;/i&gt;. Also you can imagine that the code in any of these languages would be overly complicated.&lt;/li&gt;&lt;li&gt;OK, so we definitely should use a scripting language. What options do we have?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sed, awk, perl - Learn a (cryptic) language just for the purposes of scripting? No thanks.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Python, F#, &lt;/b&gt;&lt;b&gt;Scala&lt;/b&gt; - All these languages have an amazing  property that while you are already building your applications in them, you can use them for writing quick scripts. Scala is just elegant and more innovative than F# or Python. For a deeper look how the magic with lineRegex works, see &lt;a href="http://stackoverflow.com/questions/4683682/scala-c-equivalent-of-f-active-patterns"&gt;this&lt;/a&gt;. If unfamiliar with Scala, here is a &lt;a href="http://coding-time.blogspot.com/2009/05/starting-with-scala.html"&gt;quick overview&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-686448243596346096?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/686448243596346096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2011/01/scripting-in-scala.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/686448243596346096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/686448243596346096'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2011/01/scripting-in-scala.html' title='Scripting in Scala'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-106329948041624003</id><published>2010-11-17T09:46:00.000-08:00</published><updated>2011-08-04T17:17:22.267-07:00</updated><title type='text'>Programming not fun anymore?</title><content type='html'>I'm writing this because recently I'm seeing more and more friends moving from programming to something "high level" such as management or consulting.&lt;br /&gt;&lt;br /&gt;They say they had enough of building crap database applications in a cellar with a bunch of coworkers.&lt;br /&gt;&lt;br /&gt;To all people like this I say: &lt;br /&gt;Come on guys! What's the matter with you? We used to be programmers and we kicked ass. It was your child dream. &lt;b&gt;Have you forgotten the feeling of learning your first languages and building stuff at home just for fun?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I'll tell you what - programming IS fun. What is not fun is building information systems for small businesses over and over again (actually that's one of the most boring things in the world). But building such things is not programming. Why don't you find a good programming job instead of complaining about being a servant to people who "would like one more button on the customers page"?&lt;br /&gt;&lt;br /&gt;I once had the feeling that programming is not the right thing anymore as well. I have a theory about where it comes from: It is all about this feeling of social isolation. And it goes away when you have a girlfriend you care about. It is hard to be working only with guys while wishing to meet a girl - that can be challenging. While not having the girlfriend, hanging out with non-IT friends helps a lot and when you finally have the girlfriend, you can start to love programming again.&lt;br /&gt;&lt;br /&gt;Oh, and one last thing. Did you have a feeling that programmers are not respected by non-technical people? That's not true at all. I realized when no-IT friends asked me about what my summer job was so I said "Google summer of code". The reaction was always the same - "wow!". And people tell each other and keep asking about it. More and more friends ask me "So how do all these programs and websites really work?" Ordinary people realize the importance of software and they do find awesome software awesome.&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;br /&gt;Martin&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-106329948041624003?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/106329948041624003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2010/11/programming-not-fun-anymore.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/106329948041624003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/106329948041624003'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2010/11/programming-not-fun-anymore.html' title='Programming not fun anymore?'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-7427010584598927528</id><published>2010-10-25T15:00:00.000-07:00</published><updated>2010-10-25T15:00:15.619-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='taskconnect outlook'/><title type='text'>New blogposts about programming Outlook add-ins</title><content type='html'>I published two new blogposts on the website of our add-in for Outlook called TaskConnect:&lt;br /&gt;&lt;a href="http://www.taskconnect.com/preview/blog/adding-custom-data-to-outlook-e-mails"&gt;Adding custom data to Outlook emails&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.taskconnect.com/preview/blog/searching-emails-outlook-add"&gt;Searching emails from an Outlook add-in&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Knowing the information published there before developing TaskConnect would definitely help me a lot so I'm sharing it. I hope you will also find it useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-7427010584598927528?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/7427010584598927528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2010/10/new-blogposts-about-programming-outlook.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/7427010584598927528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/7427010584598927528'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2010/10/new-blogposts-about-programming-outlook.html' title='New blogposts about programming Outlook add-ins'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-5905990081351082198</id><published>2010-04-17T07:50:00.000-07:00</published><updated>2010-11-29T16:40:49.759-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tfs outlook addin plugin'/><title type='text'>TFS addin for Outlook TaskConnect goes live!</title><content type='html'>You can download the first beta of &lt;a href="http://taskconnect.com/"&gt;TaskConnect&lt;/a&gt; now. I've been working on this for the last year with a team of cool guys in Prague.&lt;br /&gt;TaskConnect is quite unique as it integrates TFS into Outlook in a new, clever way:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;TaskConnect is a full-fledged TFS client with fulltext search field at your fingertips right in Outlook&lt;/li&gt;&lt;li&gt;Work items can be &lt;b&gt;attached&lt;/b&gt; to emails: when you are discussing a work item with someone, &lt;i&gt;the work item is visible right next to the email throughout your whole conversation&lt;/i&gt;. You can of course edit it right from Outlook.&lt;/li&gt;&lt;li&gt;Saving your time is absolutely the primary goal - speed of use is just incomparable to any existing TFS client&lt;/li&gt;&lt;/ul&gt;We think this is such a good idea that it would be silly just to support TFS. So in the future you can expect Outlook integration of many popular issue tracking systems. We also have a ton of ideas for the future and we are looking forward to your feedback and ideas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-5905990081351082198?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/5905990081351082198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2010/04/tfs-addin-for-outlook-taskconnect-goes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5905990081351082198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5905990081351082198'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2010/04/tfs-addin-for-outlook-taskconnect-goes.html' title='TFS addin for Outlook TaskConnect goes live!'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-3064995231511474624</id><published>2010-01-18T19:58:00.000-08:00</published><updated>2010-01-18T19:59:33.829-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C# delegates events'/><title type='text'>C# 4 delegates contravariance</title><content type='html'>A little quiz.&lt;br /&gt;&lt;br /&gt;Given the following two delegates:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;delegate&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EventHandler&lt;/span&gt;(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;EventArgs&lt;/span&gt; e);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;delegate&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;PropertyChangedEventHandler&lt;/span&gt;(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;PropertyChangedEventArgs&lt;/span&gt; e);&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Does the following code compile?&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt; propertyHandler(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;PropertyChangedEventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{ }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;EventHandler&lt;/span&gt; handler = propertyHandler;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Did you answer "YES, because PropertyChangedEventHandler IS an EventHandler"? &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, the answer is no. Imagine how would the following code work:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;handler(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, &lt;span style="color: blue;"&gt;new&lt;/span&gt; EventArgs());&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;How could just EventArgs be passed to propertyHandler, which expects PropertyChangedEventArgs?&lt;br /&gt;&lt;br /&gt;Actually, the exact opposite is correct in C# 4:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt; handler(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{ }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;PropertyChangedEventHandler&lt;/span&gt; propertyHandler = handler;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Then, calling&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;propertyHandler(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, &lt;span style="color: blue;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(&lt;span style="color: #a31515;"&gt;"Name"&lt;/span&gt;))&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;is perfectly ok, because the handler just sees passed PropertyChangedEventArgs as EventArgs.&lt;br /&gt;&lt;br /&gt;So the conclusion is: you can handle specialized events using less specialized handlers (you can handle eg. PropertyChanged event using just an EventHandler).&lt;br /&gt;&lt;br /&gt;For more info, see &lt;a href="see http://msdn.microsoft.com/en-us/library/ms173174%28VS.80%29.aspx"&gt;C# delegates on msdn&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-3064995231511474624?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/3064995231511474624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2010/01/c-4-delegates-contravariance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3064995231511474624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3064995231511474624'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2010/01/c-4-delegates-contravariance.html' title='C# 4 delegates contravariance'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-2828962505252040805</id><published>2009-11-09T07:18:00.000-08:00</published><updated>2009-11-09T08:01:22.588-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C# delegates implemented outer-variables'/><title type='text'>Implementation of anonymous delegates in C#</title><content type='html'>What is the output of the following program?&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: #2b91af; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb1"&gt;int&lt;/span&gt; x = 5;&lt;/p&gt;&lt;p class="cl"&gt;&lt;span class="cb2"&gt;Action&lt;/span&gt; action = (() =&amp;gt; { &lt;span class="cb2"&gt;Console&lt;/span&gt;.WriteLine(x); });&lt;/p&gt;&lt;p class="cl"&gt;x = 6;&lt;/p&gt;&lt;p class="cl"&gt;action();&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The output is of course &lt;b&gt;6&lt;/b&gt;, because delegates capture &lt;i&gt;references&lt;/i&gt; to outer variables.&lt;br /&gt;&lt;br /&gt;So how is this &lt;b&gt;implemented&lt;/b&gt; in the compiler?&lt;br /&gt;The compiler rewrites the code above to something like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;Scope&lt;/span&gt; s = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Scope&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;scope.x = 5;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;Action&lt;/span&gt; action = (scope);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;scope.x = 6;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;scope.Call();&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;and defines the Scope class like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 100%; overflow: auto; background-color: #F0F0F0;"&gt;&lt;p style="margin: 0px;"&gt;&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;Scope&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; x;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; Scope();&lt;/p&gt;&lt;p style="margin: 0px;"&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; Call()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.x);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As we would expect, the is no way to create a &lt;i&gt;reference&lt;/i&gt; to eg. an int in IL, so this is solved naturally - the int is wrapped inside Scope class and all accesses are done through the wrapper.&lt;br /&gt;The wrapper also defines the Call method, which is exactly the body of the anonymous delegate.&lt;br /&gt;&lt;br /&gt;Actually, the compiler generated name for our Scope class is "&amp;lt;&amp;gt;__DisplayClass1", and the Call method is named "&amp;lt;Main&amp;gt;b__0".&lt;br /&gt;&lt;br /&gt;For a little more complex example, see &lt;a href="http://stackoverflow.com/questions/742365/how-captured-value-in-anonymous-methods-are-implemented-in-net"&gt;this post on stackoverflow&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-2828962505252040805?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/2828962505252040805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/11/implementation-of-anonymous-delegates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/2828962505252040805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/2828962505252040805'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/11/implementation-of-anonymous-delegates.html' title='Implementation of anonymous delegates in C#'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-2355351603705345959</id><published>2009-06-14T17:08:00.001-07:00</published><updated>2009-08-23T02:50:29.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security https'/><title type='text'>HTTPS and DNS poisoning attack</title><content type='html'>The &lt;a href="http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html"&gt;best explanation of HTTPS&lt;/a&gt; I have seen was written by Jeff Moser, highly recommended!&lt;br /&gt;&lt;br /&gt;After reading the article, there was only one thing left unclear, so I asked the author, Jeff Moser, and he responded:&lt;br /&gt;&lt;br /&gt;Me:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Just one thing is really unclear to me - DNS poisoning: The attacker obtains certificate from amazon.com, I enter "amazon.com" to browser, browser goes to attacker's site, which responds by valid amazon.com certificate signed by Verisign. How does the browser tell this is an attack?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Jeff:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Great question! Note that if an attacker did this, they'd run into trouble in the "Trading Secrets" section that I described. Without knowing Amazon.com's private key, they couldn't decrypt the pre-master secret that the client sends out because the certificate from Verisign has Amazon's public key. Thus, the client would use that public key (and not one an attacker generated).&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/DNS_cache_poisoning"&gt;DNS poisoning&lt;/a&gt; is an attack when attacker fools DNS server. You type "amazon.com" in the browser, the browser asks the DNS server to resolve the URL = to translate the URL to IP address. Since the DNS server is poisoned, it returns attacker's IP address and browser connects to attacker's server, while address bar reads "amazon.com" - quite nasty.&lt;br /&gt;&lt;br /&gt;Now everything is 100% clear, thanks Jeff!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-2355351603705345959?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/2355351603705345959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/06/https-and-dns-poisoning-attack.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/2355351603705345959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/2355351603705345959'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/06/https-and-dns-poisoning-attack.html' title='HTTPS and DNS poisoning attack'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-3558259345318545966</id><published>2009-06-12T05:02:00.000-07:00</published><updated>2009-06-22T17:08:14.899-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c# custom format double'/><title type='text'>Custom IFormatProvider for doubles</title><content type='html'>The following example shows how to write a custom &lt;span style="color:#2b91af"&gt; IFormatProvider&lt;/span&gt; which you can use in &lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color:#2b91af"&gt;IFormatProvider&lt;/span&gt;, ...).&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: #2b91af; }.cb3 { color: green; }.cb4 { color: #a31515; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;DoubleFormatter&lt;/span&gt; : &lt;span class="cb2"&gt;IFormatProvider&lt;/span&gt;, &lt;span class="cb2"&gt;ICustomFormatter&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;{&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// always use dot separator for doubles&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;CultureInfo&lt;/span&gt; enUsCulture =&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;CultureInfo&lt;/span&gt;.GetCultureInfo(&lt;span class="cb4"&gt;"en-US"&lt;/span&gt;);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;string&lt;/span&gt; Format(&lt;span class="cb1"&gt;string&lt;/span&gt; format, &lt;span class="cb1"&gt;object&lt;/span&gt; arg, &lt;/p&gt;&lt;p class="cl"&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;&amp;nbsp; &lt;span class="cb2"&gt;IFormatProvider&lt;/span&gt; formatProvider)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// format doubles to 3 decimal places&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; &lt;span class="cb1"&gt;string&lt;/span&gt;.Format(enUsCulture, &lt;span class="cb4"&gt;"{0:0.000}"&lt;/span&gt;, arg);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;object&lt;/span&gt; GetFormat(&lt;span class="cb2"&gt;Type&lt;/span&gt; formatType)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; (formatType == &lt;span class="cb1"&gt;typeof&lt;/span&gt;(&lt;span class="cb2"&gt;ICustomFormatter&lt;/span&gt;)) &lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ? &lt;span class="cb1"&gt;this&lt;/span&gt; : &lt;span class="cb1"&gt;null&lt;/span&gt;;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Having this formatter, we can use it like this:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb5 { color: blue; }.cb6 { color: #2b91af; }.cb7 { color: #a31515; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb5"&gt;double&lt;/span&gt; width = 15.77555;&lt;/p&gt;&lt;p class="cl"&gt;&lt;span class="cb5"&gt;double&lt;/span&gt; height = 12.8497979;&lt;/p&gt;&lt;p class="cl"&gt;&lt;span class="cb6"&gt;Console&lt;/span&gt;.WriteLine(&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb5"&gt;string&lt;/span&gt;.Format(&lt;span class="cb5"&gt;new&lt;/span&gt; &lt;span class="cb6"&gt;DoubleFormatter&lt;/span&gt;(), &lt;span class="cb7"&gt;"w={0} h={1}"&lt;/span&gt;, width, height));&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output: &lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;w=15.776 h=12.850&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So now we have a reusable format for doubles - 3 decimal places with dot separator. That is nice, but this formatter is very simple - it formats &lt;span style="font-style:italic;"&gt;everything (eg. DateTime)&lt;/span&gt; as "0:000". This is a fast version if you know that you will only use it for formatting lots of doubles.&lt;br /&gt;&lt;br /&gt;The real version should look like this:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb10 { color: blue; }.cb12 { color: #2b91af; }.cb13 { color: green; }.cb14 { color: #a31515; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb10"&gt;public&lt;/span&gt; &lt;span class="cb10"&gt;class&lt;/span&gt; &lt;span class="cb12"&gt;DoubleFormatter&lt;/span&gt; : &lt;span class="cb12"&gt;IFormatProvider&lt;/span&gt;, &lt;span class="cb12"&gt;ICustomFormatter&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;{&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb13"&gt;// always use dot separator for doubles&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;private&lt;/span&gt; &lt;span class="cb12"&gt;CultureInfo&lt;/span&gt; enUsCulture =&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb12"&gt;CultureInfo&lt;/span&gt;.GetCultureInfo(&lt;span class="cb14"&gt;"en-US"&lt;/span&gt;);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;public&lt;/span&gt; &lt;span class="cb10"&gt;string&lt;/span&gt; Format(&lt;span class="cb10"&gt;string&lt;/span&gt; format, &lt;span class="cb10"&gt;object&lt;/span&gt; arg, &lt;/p&gt;&lt;p class="cl"&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 class="cb12"&gt;IFormatProvider&lt;/span&gt; formatProvider)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;if&lt;/span&gt; (arg &lt;span class="cb10"&gt;is&lt;/span&gt; &lt;span class="cb10"&gt;double&lt;/span&gt;)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;if&lt;/span&gt; (&lt;span class="cb10"&gt;string&lt;/span&gt;.IsNullOrEmpty(format))&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&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 class="cb13"&gt;// by default, format doubles to 3 decimal places&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&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 class="cb10"&gt;return&lt;/span&gt; &lt;span class="cb10"&gt;string&lt;/span&gt;.Format(enUsCulture, &lt;span class="cb14"&gt;"{0:0.000}"&lt;/span&gt;, arg);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&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 class="cb13"&gt;// if user supplied own format use it&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&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 class="cb10"&gt;return&lt;/span&gt; ((&lt;span class="cb10"&gt;double&lt;/span&gt;)arg).ToString(format, enUsCulture);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb13"&gt;// format everything else normally&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;if&lt;/span&gt; (arg &lt;span class="cb10"&gt;is&lt;/span&gt; &lt;span class="cb12"&gt;IFormattable&lt;/span&gt;)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;return&lt;/span&gt; ((&lt;span class="cb12"&gt;IFormattable&lt;/span&gt;)arg).ToString(format, formatProvider);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;else&lt;/span&gt; &lt;span class="cb10"&gt;return&lt;/span&gt; arg.ToString();&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;public&lt;/span&gt; &lt;span class="cb10"&gt;object&lt;/span&gt; GetFormat(&lt;span class="cb12"&gt;Type&lt;/span&gt; formatType)&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb10"&gt;return&lt;/span&gt; (formatType == &lt;span class="cb10"&gt;typeof&lt;/span&gt;(&lt;span class="cb12"&gt;ICustomFormatter&lt;/span&gt;)) ? &lt;span class="cb10"&gt;this&lt;/span&gt; : &lt;span class="cb10"&gt;null&lt;/span&gt;;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p class="cl"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb221 { color: #2b91af; }.cb22 { color: blue; }.cb23 { color: #a31515; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb221"&gt;Console&lt;/span&gt;.WriteLine(&lt;span class="cb22"&gt;string&lt;/span&gt;.Format(&lt;span class="cb22"&gt;new&lt;/span&gt; &lt;span class="cb221"&gt;DoubleFormatter&lt;/span&gt;(),&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb23"&gt;"Numbers {0} and {1:0.0}."&lt;/span&gt; +&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb23"&gt;"Now a string {2}, a number {3}, date {4} and object: {5}"&lt;/span&gt;,&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.234567, -0.57123456, &lt;span class="cb23"&gt;"Hi!"&lt;/span&gt;, 5, &lt;span class="cb221"&gt;DateTime&lt;/span&gt;.Now, &lt;span class="cb22"&gt;new&lt;/span&gt; &lt;span class="cb22"&gt;object&lt;/span&gt;()));&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;Numbers 1.235 and -0.6. Now a string Hi!, a number 5, date 12.6.2009 17:11:35 and object: System.Object&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This article should give you an overview of implementing custom IFormatProvider. Now you should be able to modify the code to suit your specific needs.&lt;br /&gt;&lt;br /&gt;Other examples with custom formatters can be found in MSDN. See example with &lt;a href="http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx"&gt;formatter for 12-digit account numbers&lt;/a&gt; (12345–678–9012).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-3558259345318545966?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/3558259345318545966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/06/custom-iformatprovider-for-doubles.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3558259345318545966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3558259345318545966'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/06/custom-iformatprovider-for-doubles.html' title='Custom IFormatProvider for doubles'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-5205287485437086117</id><published>2009-06-04T05:55:00.000-07:00</published><updated>2009-06-04T06:32:42.021-07:00</updated><title type='text'>Associating data with an event</title><content type='html'>I just solved the following problem - best explained by concrete example: &lt;br /&gt;&lt;br /&gt;WPF Animation.Completed is an event. I need to register this event and when it fires, access custom data associated with the event:&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: #2b91af; }.cb3 { color: green; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb1"&gt;void&lt;/span&gt; animate(Graph graph)&lt;/p&gt;&lt;p class="cl"&gt;{&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;PointAnimation&lt;/span&gt; anim = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;PointAnimation&lt;/span&gt;();&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; anim.Completed += &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;EventHandler&lt;/span&gt;(anim_Completed);&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// in anim_Completed, I want to call graph.Fix() - how?&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;}&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="cl"&gt;&lt;span class="cb1"&gt;void&lt;/span&gt; anim_Completed(&lt;span class="cb1"&gt;object&lt;/span&gt; sender, &lt;span class="cb2"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p class="cl"&gt;{&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// how do I access 'graph' here?&lt;/span&gt;&lt;/p&gt;&lt;p class="cl"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Seems like a tough problem. Remembering 'graph' in eg. static variable is not an option, especially if we have more graphs animated at the same time.&lt;br /&gt;Fortunately, C#'s lambdas come to the rescue:&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: #2b91af; }&lt;/style&gt;&lt;div class="cf"&gt;&lt;p class="cl"&gt;&lt;span class="cb1"&gt;void&lt;/span&gt; animate(Graph graph)&lt;/p&gt;&lt;p class="cl"&gt;{&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;PointAnimation&lt;/span&gt; anim = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;PointAnimation&lt;/span&gt;();&lt;/p&gt;&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; anim.Completed += &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;EventHandler&lt;/span&gt;((s, e) =&amp;gt; { graph.Fix(); });&lt;/p&gt;&lt;p class="cl"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This works because anonymous methods &lt;a href="http://www.west-wind.com/weblog/posts/330694.aspx"&gt;bind to outer variables&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-5205287485437086117?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/5205287485437086117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/06/associating-data-with-event.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5205287485437086117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5205287485437086117'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/06/associating-data-with-event.html' title='Associating data with an event'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-153432439052324958</id><published>2009-05-16T15:21:00.000-07:00</published><updated>2011-05-07T02:32:27.993-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala tutorial'/><title type='text'>Starting with Scala - slides from presentation</title><content type='html'>I started learning &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; programming language.&lt;br /&gt;&lt;br /&gt;Scala rocks! It is &lt;b&gt;statically typed&lt;/b&gt;, has functional features, and aims for developer &lt;b&gt;productivity&lt;/b&gt;. In Scala you can express what you want with &lt;b&gt;less code&lt;/b&gt; than in C#. Scala runs on JVM and any Java code can be called from Scala.&lt;br /&gt;&lt;!--&lt;iframe frameborder="0" height="327" scrolling="no" src="http://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SD2F35756F15DFA8BB%21147&amp;amp;p4=" width="402"&gt;&lt;/iframe&gt;&lt;br /&gt;--&gt;&lt;br /&gt;Here are the slides from my presentation at Charles University in Prague:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://artax.karlin.mff.cuni.cz/%7Ekonim5am/Scala/Scala.pdf"&gt;pdf&lt;/a&gt;, &lt;a href="http://artax.karlin.mff.cuni.cz/%7Ekonim5am/Scala/Scala.pptx"&gt;powerpoint&lt;/a&gt;, &lt;a href="http://artax.karlin.mff.cuni.cz/%7Ekonim5am/Scala/ScalaExamples.zip"&gt;examples (.zip)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some of Scala's clever concepts suprised me:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Actors - a totally different thinking about concurrency than you are used to. No threads + shared state + locks. Actors live independently, share no state, and communicate by sending each other messages.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Adding new keywords to the language just by writing ordinary methods. Consider adding C#'s &lt;span style="font-style: italic;"&gt;using&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;lock&lt;/span&gt; keyword to Scala, without compiler support!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Traits - behaviors can be mixed in freely at instatiation time, sort of built-in Strategy design pattern.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Absence of the &lt;span style="font-style: italic;"&gt;static&lt;/span&gt; keyword, turns out it is not needed! Instead of having static state and methods of a class, you declare a singleton instance and call its methods.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If you want to see concrete examples, check out the slides.. it's coding time ;)&lt;br /&gt;&lt;br /&gt;Links to get started:&lt;br /&gt;&lt;a href="http://www.artima.com/scalazine/articles/steps.html"&gt;First steps to Scala&lt;/a&gt; - a great tutorial.&lt;br /&gt;&lt;a href="http://www.artima.com/scalazine/articles/twitter_on_scala.html"&gt;Twitter on Scala - detailed interview&lt;/a&gt; - did you know that Twitter runs on Scala?&lt;br /&gt;&lt;br /&gt;Thanks to my friends Joe and Pz for support!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-153432439052324958?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/153432439052324958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/05/starting-with-scala.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/153432439052324958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/153432439052324958'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/05/starting-with-scala.html' title='Starting with Scala - slides from presentation'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-3338217496795990885</id><published>2009-04-22T02:52:00.000-07:00</published><updated>2009-04-22T03:20:01.757-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sharpdevelop GSoC'/><title type='text'>I'm in!</title><content type='html'>Great news! I've been accepted to Google summer of code. I'll be working on debugger visualizers for &lt;a href="http://socghop.appspot.com/org/home/google/gsoc2009/sharpdevelop"&gt;SharpDevelop&lt;/a&gt;.&lt;br /&gt;This is a great opportunity to continue my work on the Object graph visualizer, and even get it integrated in an open source IDE.&lt;br /&gt;I'll be also working on other visualizers and things (particularly one of them totally cool in my opinion).&lt;br /&gt;Cool thing about this is that none of the visualizers is present in Visual Studio.&lt;br /&gt;Hope the visualizers will make your debugging experience even better :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-3338217496795990885?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/3338217496795990885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/04/im-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3338217496795990885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/3338217496795990885'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/04/im-in.html' title='I&apos;m in!'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-6058539838334737026</id><published>2009-03-31T06:01:00.000-07:00</published><updated>2009-04-01T17:44:56.702-07:00</updated><title type='text'>Debugger Visualizer for Visual Studio</title><content type='html'>Recently, I have been playing with implementing a Visual Studio add-in that displays your data structures as graphs live as you debug.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_FfbezKs1jgs/SdP725xkpkI/AAAAAAAAAtE/tlEIdvni5MM/s1600-h/fabricScreen1.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 177px;" src="http://1.bp.blogspot.com/_FfbezKs1jgs/SdP725xkpkI/AAAAAAAAAtE/tlEIdvni5MM/s320/fabricScreen1.png" alt="" id="BLOGGER_PHOTO_ID_5319872505494939202" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The graph on the right shows current state of the data structure being watched. The graph updates as you step through the code.&lt;br /&gt;Here is an example of more complex structure:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_FfbezKs1jgs/SdP8_7bhevI/AAAAAAAAAtM/ux-0WWet5yU/s1600-h/fabricScreen3.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 213px;" src="http://2.bp.blogspot.com/_FfbezKs1jgs/SdP8_7bhevI/AAAAAAAAAtM/ux-0WWet5yU/s320/fabricScreen3.png" alt="" id="BLOGGER_PHOTO_ID_5319873760069778162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The layout is done using GLEE graph layout engine, which could be possibly replaced by Graphviz or something else.&lt;br /&gt;&lt;br /&gt;As I was suspecting prior to the implementation, there is an important issue that needs to be solved: when the user does a step in the debugger, the object graph is rebuilt from scratch and the layout engine calculates new layout. However, even if the graph changes only slightly, it can sometimes affect the layout significantly and therefore confuse the user.&lt;br /&gt;I am currently thinking about matching nodes from current step to the nodes from the previous step (provided the graph doesn't change that much between steps, which is typically true - and when it chages too much, we don't mind layout changes anyway). The matching of the two graphs could be used to preserve the layout until the nodes really have to move. And if they have to move, move them in a way that they preserve relative positions to each other. There is a space for some interesting algorithms here.&lt;br /&gt;&lt;br /&gt;Current source code of the add-in is available &lt;a href="http://artax.karlin.mff.cuni.cz/%7Ekonim5am/Fabric-source.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-6058539838334737026?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/6058539838334737026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2009/03/debugger-visualizer-for-visual-studio.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6058539838334737026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6058539838334737026'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2009/03/debugger-visualizer-for-visual-studio.html' title='Debugger Visualizer for Visual Studio'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_FfbezKs1jgs/SdP725xkpkI/AAAAAAAAAtE/tlEIdvni5MM/s72-c/fabricScreen1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-7502497841295232569</id><published>2008-04-16T13:46:00.001-07:00</published><updated>2011-03-18T04:50:24.362-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='svn video tutorial'/><title type='text'>Subversion visually explained in 30 sec - svn tutorial</title><content type='html'>This video tutorial tries to explain the basics of how SVN is used. The buttons at the bottom are movie controls. Scroll down for conflict explanation.&lt;br /&gt;&lt;object data="http://aliensystems.ic.cz/svn.swf" height="440" type="application/x-shockwave-flash" width="590"&gt; &lt;p&gt;svn.swf&lt;/p&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;This explains a conflict while working with Subversion:&lt;br /&gt;&lt;object data="http://aliensystems.ic.cz/svn_conflict.swf" height="440" type="application/x-shockwave-flash" width="590"&gt; &lt;p&gt;svn_conflict.swf&lt;/p&gt;&lt;/object&gt;&lt;br /&gt;Summary of SVN commands (do these commands with TortoiseSVN by right clicking on a file or directory):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;h2&gt;SVN checkout&lt;/h2&gt;The first command to use Subversion. Downloads repository contents to a folder on your PC, makes this folder special SVN folder with SVN icon.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Update&lt;/h2&gt;Merges new changes from repository to your working copy. Update before every commit is important because of possible conflicts, that must be resolved by conversation with your teammate, because concurrent changes cannot be resolved automatically.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Commit&lt;/h2&gt;Megres changes from your yorking copy to SVN repository.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Resolved&lt;/h2&gt;Tells SVN that the conflicted file is now OK.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Add&lt;/h2&gt;Schedules new file to be saved to repository with next commit.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Delete&lt;/h2&gt;Shedules file to be deleted from repository with next commit. SVN keeps all history, so accidental deletes are not a problem.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Revert&lt;/h2&gt;Undoes all changes to your working copy since last commit. Usefull if you really mess up and want to throw away the changes and start over.&lt;/li&gt;&lt;li&gt;&lt;h2&gt;Log&lt;/h2&gt;Shows nice log of changes sorted by date, even with simple statistics.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f04%2fsubversion-visually-explained-in-30sec.html"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f04%2fsubversion-visually-explained-in-30sec.html" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-7502497841295232569?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/7502497841295232569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2008/04/subversion-visually-explained-in-30sec.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/7502497841295232569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/7502497841295232569'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2008/04/subversion-visually-explained-in-30sec.html' title='Subversion visually explained in 30 sec - svn tutorial'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-5333443073675640560</id><published>2008-03-28T05:26:00.001-07:00</published><updated>2011-06-16T09:21:20.154-07:00</updated><title type='text'>Why does XML have attributes?</title><content type='html'>Have you ever wondered why there are also attributes in XML and not just elements, causing many never-ending "element vs attribute" discussions?&lt;br /&gt;And why is XML so redundant - repeating the tag name in the ending tag, thus making the document much larger?&lt;br /&gt;I asked &lt;a href="http://www.sgmlsource.com/"&gt;Charles Goldfarb&lt;/a&gt;, the author of &lt;a href="http://en.wikipedia.org/wiki/Sgml"&gt;SGML&lt;/a&gt; - the original format from the 1960s (already had &amp;lt;tags&amp;gt; and attributes) from which XML and HTML were derived.&lt;br /&gt;He was very kind to reply to me. Enjoy:&lt;br /&gt;&lt;pre&gt;&lt;cite&gt;&lt;br /&gt;- In &amp;lt;elem&amp;gt;text&amp;lt;/elem&amp;gt;, why repeat "elem" for the second time?&lt;br /&gt;&lt;/cite&gt;&lt;br /&gt;In fact, there is an option in SGML that allows you to omit the element-type&lt;br /&gt;name from an end-tag, but it is rarely supported. (In XML the option does not&lt;br /&gt;exist at all.) The name is there primarily for the convenience of humans&lt;br /&gt;debugging the markup, as there are large document types, such as aircraft&lt;br /&gt;maintenance manuals, where elements can nest very deeply.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;cite&gt;&lt;br /&gt;- Why are there attributes in SGML? One could express the same just with elements.&lt;br /&gt;&lt;/cite&gt;&lt;br /&gt;In fact, one could just as easily express the same just with attributes!&lt;br /&gt;&lt;br /&gt;The basic notion is that elements represent objects while attributes represent&lt;br /&gt;their properties. However, the property "content" is given a convenient syntax&lt;br /&gt;-- everything between the start-tag and matching end-tag -- which makes it&lt;br /&gt;simpler to express content hierarchy by simply nesting elements.&lt;br /&gt;&lt;br /&gt;In a nutshell, if information is part of the content of the document, represent&lt;br /&gt;it as an element. If it is some other property, represent it as an attribute.&lt;br /&gt;&lt;br /&gt;I wish you the best of luck with your studies.&lt;br /&gt;&lt;br /&gt;Charles Goldfarb&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;©2008 Charles F. Goldfarb * &lt;a class="moz-txt-link-abbreviated" href="http://www.xmlhandbook.com/"&gt;www.xmlhandbook.com&lt;/a&gt; * &lt;a class="moz-txt-link-abbreviated" href="http://www.xmlbooks.com/"&gt;www.xmlbooks.com&lt;/a&gt;&lt;br /&gt;The XML Handbook?* 5th Edition ISBN 0-13-049765-7 * 100,000 in print!&lt;br /&gt;--&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fever-wondered-why-xml-has-attributes.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fever-wondered-why-xml-has-attributes.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-5333443073675640560?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/5333443073675640560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2008/03/ever-wondered-why-xml-has-attributes.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5333443073675640560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/5333443073675640560'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2008/03/ever-wondered-why-xml-has-attributes.html' title='Why does XML have attributes?'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-1899043711676839304</id><published>2008-03-17T14:18:00.000-07:00</published><updated>2011-03-18T07:24:18.005-07:00</updated><title type='text'>Implement your own Parallel.For in C#</title><content type='html'>This article is intended for .NET 2 or 3.5. If you are on &lt;b&gt;.NET 4&lt;/b&gt;, use &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.parallel_members%28VS.100%29.aspx"&gt;System.Threading.Parallel&lt;/a&gt; class.&lt;br /&gt;&lt;br /&gt;I was thinking about how Parallel.For could be implemented. I wrote my own, I am using it in my own project and it scales very well.&lt;br /&gt;&lt;br /&gt;Here it is:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: #2b91af; }.cb3 { color: gray; }.cb4 { color: green; }&lt;/style&gt;&lt;br /&gt;&lt;div class="cf"&gt;&lt;div class="cl"&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Parallel&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;{&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; Parallel for loop. Invokes given action, passing arguments &lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; fromInclusive - toExclusive on multiple threads.&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; Returns when loop finished.&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;static&lt;/span&gt; &lt;span class="cb1"&gt;void&lt;/span&gt; For(&lt;span class="cb1"&gt;int&lt;/span&gt; fromInclusive, &lt;span class="cb1"&gt;int&lt;/span&gt; toExclusive, &lt;span class="cb1"&gt;Action&lt;int&gt;&lt;/int&gt;&lt;/span&gt; action)&lt;/div&gt;&lt;div class="cl"&gt;{&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// chunkSize = 1 makes items to be processed in order.&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// Bigger chunk size should reduce lock waiting time and thus&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// increase paralelism.&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;int&lt;/span&gt; chunkSize = 4;&lt;/div&gt;&lt;div class="cl"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// number of process() threads&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;int&lt;/span&gt; threadCount = &lt;span class="cb2"&gt;Environment&lt;/span&gt;.ProcessorCount;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;int&lt;/span&gt; index = fromInclusive - chunkSize;&lt;br /&gt;&lt;span class="cb4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="cb4"&gt;// locker object shared by all the process() delegates&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span class="cb2"&gt;var&lt;/span&gt; locker = new &lt;span class="cb1"&gt;object&lt;/span&gt;();&lt;/div&gt;&lt;div class="cl"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// processing function&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// takes next chunk and processes it using action&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;var&lt;/span&gt; process = &lt;span class="cb1"&gt;delegate&lt;/span&gt;()&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;while&lt;/span&gt; (&lt;span class="cb1"&gt;true&lt;/span&gt;)&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;int&lt;/span&gt; chunkStart = 0;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;lock&lt;/span&gt; (locker)&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&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 class="cb4"&gt;// take next chunk&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&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; index += chunkSize;&lt;/div&gt;&lt;div class="cl"&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; chunkStart = index;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// process the chunk&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// (another thread is processing another chunk&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="cb4"&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; so the real order of items will be out-of-order)&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;for&lt;/span&gt; (&lt;span class="cb1"&gt;int&lt;/span&gt; i = chunkStart;&amp;nbsp; i &amp;lt; chunkStart + chunkSize; i++)&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&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 class="cb1"&gt;if&lt;/span&gt; (i &amp;gt;= toExclusive) &lt;span class="cb1"&gt;return&lt;/span&gt;;&lt;/div&gt;&lt;div class="cl"&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; action(i);&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/div&gt;&lt;div class="cl"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// launch process() threads&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;IAsyncResult&lt;/span&gt;[] asyncResults = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;IAsyncResult&lt;/span&gt;[threadCount];&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;for&lt;/span&gt; (&lt;span class="cb1"&gt;int&lt;/span&gt; i = 0; i &amp;lt; threadCount; ++i)&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; asyncResults[i] = process.BeginInvoke(&lt;span class="cb1"&gt;null&lt;/span&gt;, &lt;span class="cb1"&gt;null&lt;/span&gt;);&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb4"&gt;// wait for all threads to complete&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;for&lt;/span&gt; (&lt;span class="cb1"&gt;int&lt;/span&gt; i = 0; i &amp;lt; threadCount; ++i)&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; process.EndInvoke(asyncResults[i]);&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div class="cl"&gt;}&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As noted in the code, by setting chunkSize to 1 we can make the items be processed in order. With bigger chunk size, items can be processed in mixed non-deterministic order, which is ok in some application, like when you want to modify all items of a collection or render lines of a picture.&lt;br /&gt;Bigger chunkSize should reduce lock waiting time and thus increase overall speed. But too big chunkSize is bad too, because if the work is split into only a few big parts, there is not enough parallelism exposed - we could find ourselves waiting for the last single thread to finish its large chunk.&lt;br /&gt;&lt;br /&gt;Using Parallel.For is simple:&lt;br /&gt;&lt;style type="text/css"&gt;.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; border:1px solid black; padding: 8pt; width: 94%; overflow: auto; background-color: #F0F0F0; }.cl { margin: 0px; }.cb1 { color: #2b91af; }.cb2 { color: blue; }.cb3 { color: green; }&lt;/style&gt;&lt;br /&gt;&lt;div class="cf"&gt;&lt;div class="cl"&gt;&lt;span class="cb1"&gt;Parallel&lt;/span&gt;.For(0, 1000, &lt;span class="cb2"&gt;delegate&lt;/span&gt;(&lt;span class="cb2"&gt;int&lt;/span&gt; i)&lt;/div&gt;&lt;div class="cl"&gt;{&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// your parallel code&lt;/span&gt;&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Thread&lt;/span&gt;.Sleep(100);&lt;/div&gt;&lt;div class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Console&lt;/span&gt;.WriteLine(i);&lt;/div&gt;&lt;div class="cl"&gt;});&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fimplement-your-own-parallelfor-in-c.html"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fimplement-your-own-parallelfor-in-c.html" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-1899043711676839304?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/1899043711676839304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2008/03/implement-your-own-parallelfor-in-c.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/1899043711676839304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/1899043711676839304'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2008/03/implement-your-own-parallelfor-in-c.html' title='Implement your own Parallel.For in C#'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4177053433240488765.post-6378615773513622724</id><published>2008-03-14T14:59:00.000-07:00</published><updated>2008-03-28T18:49:16.030-07:00</updated><title type='text'>Serialize object graph to XML in .Net</title><content type='html'>&lt;span style="color: rgb(0, 0, 0);"&gt;How to serialize any data structure to XML? My first idea was XmlSerializer. But then I found out it had some serious drawbacks. Luckily, there is a better option - &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;NetDataContractSerializer.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;In .Net, there are a few classes for (de)serialization. This is an overview of their features:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;XmlSerializer&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Cannot serialize circular references.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;If more objects point to the same object, its copies are created in the xml for each of these references.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Has to know all types that could be encountered during serialization in advance - throws an exception on unknown type. Known types are passed in the constructor to XmlSerializer or marked by XmlIncludeAttribute.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Generates simple readable xml.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;DataContractSerializer&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Has to know types in advance - like XmlSerializer.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Can serialize circular references - construct with preserveObjectReferences = true&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Used by WCF.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;NetDataContractSerializer - better!&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Serializes object graph properly including circular references.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Doesn't have to know types in advance.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;However,  &lt;/span&gt;&lt;a style="color: rgb(51, 102, 255);" href="http://msdn2.microsoft.com/en-us/library/system.runtime.serialization.netdatacontractserializer.aspx"&gt;MSDN&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; states that it can be only used in .Net &lt;-&gt; .Net communication, which is ok also for storing object in a file.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Generates simple readable xml.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;BinarryFormatter&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Works well, like NetDataContractSerializer.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Disadvantage is that it serializes to &lt;span style="font-style: italic;"&gt;binary&lt;/span&gt; format, which make its unusable e.g. for saving to a file that user could later edit.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;The output is smallest thanks to the binary format.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;SoapFormatter&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Deprecated. Cannot serialize generic collections&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;- All serializers need the type to be serialized marked by SerializableAttribute.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fserialize-object-graph-to-xml-in-net.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fserialize-object-graph-to-xml-in-net.html" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;What does it mean that XmlSerializer has to &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;know all types that could be encountered during serialization in advance&lt;/span&gt;?&lt;br /&gt;Imagine that we have two classes: Base and Derived.&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt; &lt;div    style="border: 1px solid black; padding: 8pt; background: rgb(240, 240, 240) none repeat scroll 0% 50%; overflow: auto; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 94%;font-family:Courier New;font-size:10pt;color:black;"&gt; &lt;p style="margin: 0px;"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Base&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; name;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;public&lt;/span&gt; Base()&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            name = &lt;span style="color: rgb(163, 21, 21);"&gt;"base instance"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    }&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;    [&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;Base&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; left;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; right;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;public&lt;/span&gt; Derived()&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    }&lt;/p&gt; &lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;What if we have a reference to Base and we actually don't want to care about the actual type?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;div    style="border: 1px solid black; padding: 8pt; background: rgb(240, 240, 240) none repeat scroll 0% 50%; overflow: auto; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 94%;font-family:Courier New;font-size:10pt;color:black;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Base&lt;/span&gt; b = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;// we only know we are holding reference to Base&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;// and we don't want to care about the actual type&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;XmlSerializer&lt;/span&gt; ser = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;XmlSerializer&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;Base&lt;/span&gt;));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;// serialize&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;FileStream&lt;/span&gt; fs = &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.Create(&lt;span style="color: rgb(43, 145, 175);"&gt;AppDomain&lt;/span&gt;.CurrentDomain.BaseDirectory + &lt;span style="color: rgb(163, 21, 21);"&gt;"data.xml"&lt;/span&gt;))&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:green;"&gt;// XmlSerializer throws an Exception&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    ser.Serialize(fs, b);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;// deserialize&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;FileStream&lt;/span&gt; fs = &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.OpenRead(&lt;span style="color: rgb(43, 145, 175);"&gt;AppDomain&lt;/span&gt;.CurrentDomain.BaseDirectory + &lt;span style="color: rgb(163, 21, 21);"&gt;"data.xml"&lt;/span&gt;))&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;    Base&lt;/span&gt; baseDeserialized = (&lt;span style="color: rgb(43, 145, 175);"&gt;Base&lt;/span&gt;)ser.Deserialize(fs); &lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; deserialize = baseDeserialized &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;XmlSerializer throws an exception, because it encounters an "unknown" type - Derived. We could solve this by passing all the possible derived types in constructor of XmlSerializer or tagging all by XmlIncludeAttribute. This is of course inconvenient if you have a lot of classes. The worst thing is that when you add a derived class, you have to change code elsewhere.&lt;br /&gt;NetDataContractSerializer doesn't have this problem.&lt;br /&gt;&lt;br /&gt;The second issue with XmlSerializer is that it cannot serialize complex object graph. What does it mean "to serialize object graph"?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;div    style="border: 1px solid black; padding: 8pt; background: rgb(240, 240, 240) none repeat scroll 0% 50%; overflow: auto; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 94%;font-family:Courier New;font-size:10pt;color:black;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; top = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.left = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.left.name = &lt;span style="color: rgb(163, 21, 21);"&gt;"left son"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.right = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.right.name = &lt;span style="color: rgb(163, 21, 21);"&gt;"right son"&lt;/span&gt;; &lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.left.right = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;//         top&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;//       /     \&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;//  left       right&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;//       \     /&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;//        bottom&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;top.right.left = top.left.right;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;XmlSerializer&lt;/span&gt; ser = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;XmlSerializer&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;FileStream&lt;/span&gt; fs = &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.Create(&lt;span style="color: rgb(43, 145, 175);"&gt;AppDomain&lt;/span&gt;.CurrentDomain.BaseDirectory + &lt;span style="color: rgb(163, 21, 21);"&gt;"data.xml"&lt;/span&gt;))&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    ser.Serialize(fs, top);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;FileStream&lt;/span&gt; fs = &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.OpenRead(&lt;span style="color: rgb(43, 145, 175);"&gt;AppDomain&lt;/span&gt;.CurrentDomain.BaseDirectory + &lt;span style="color: rgb(163, 21, 21);"&gt;"data.xml"&lt;/span&gt;))&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt; deserialized = (&lt;span style="color: rgb(43, 145, 175);"&gt;Derived&lt;/span&gt;)ser.Deserialize(fs);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:green;"&gt;    // false - we want true&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;bool&lt;/span&gt; ok = deserialized.left.right == deserialized.right.left;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;After deserialization, &lt;/span&gt;deserialized.left.right == deserialized.right.left is false, that means the object graph is different. Worse - XmlSerializer cannot serialize circular references at all.&lt;br /&gt;Again, &lt;span style="color: rgb(0, 0, 0);"&gt;NetDataContractSerializer &lt;/span&gt;doesn't have any of these problems.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fserialize-object-graph-to-xml-in-net.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcoding-time.blogspot.com%2f2008%2f03%2fserialize-object-graph-to-xml-in-net.html" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4177053433240488765-6378615773513622724?l=coding-time.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-time.blogspot.com/feeds/6378615773513622724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://coding-time.blogspot.com/2008/03/serialize-object-graph-to-xml-in-net.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6378615773513622724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4177053433240488765/posts/default/6378615773513622724'/><link rel='alternate' type='text/html' href='http://coding-time.blogspot.com/2008/03/serialize-object-graph-to-xml-in-net.html' title='Serialize object graph to XML in .Net'/><author><name>Inv</name><uri>http://www.blogger.com/profile/13169352488655771114</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-GrwzFL2brSk/TYNFtlUFzqI/AAAAAAAABDk/Xy61AUCNNGo/s1600/c6641a591f30cccc513a1e9ea33f7944.jpg%253Fsize%253D200'/></author><thr:total>3</thr:total></entry></feed>
