<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>TLK's blog: iDotNet development, eh?</title>
	<atom:link href="http://blog.T-L-K.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.T-L-K.com</link>
	<description>.NET development, iPhone development</description>
	<pubDate>Mon, 13 Apr 2009 12:49:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>C# 4.0: Covariance and Contravariance</title>
		<link>http://blog.T-L-K.com/dot-net/2009/c-sharp-4-covariance-and-contravariance</link>
		<comments>http://blog.T-L-K.com/dot-net/2009/c-sharp-4-covariance-and-contravariance#comments</comments>
		<pubDate>Mon, 13 Apr 2009 08:30:39 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=127</guid>
		<description><![CDATA[In this article I&#8217;ll try to cover one of the C# 4.0 innovations. One of the new features is covariance and contravariance on type parameters that is now supported by generic delegates and generic interfaces. First let&#8217;s see what does these words mean :)
Generally if we have some entity (interface or delegate) that is generic [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I&#8217;ll try to cover one of the C# 4.0 innovations. One of the new features is covariance and contravariance on type parameters that is now supported by generic delegates and generic interfaces. First let&#8217;s see what does these words mean :)</p>
<p>Generally if we have some entity (interface or delegate) that is generic on type <tt>T</tt> – some <tt>Entity&lt;T&gt;</tt>, and two concrete entities <tt>Entity&lt;A&gt;</tt> and <tt>Entity&lt;B&gt;</tt> where <tt>B</tt> inherits from <tt>A</tt>, then there are no inheritance relationships between <tt>Entity&lt;A&gt;</tt> and <tt>Entity&lt;B&gt;</tt>. Covariance (and contravariance) adds such relationships:</p>
<p><span id="more-127"></span>If there is some <tt>CoEntity&lt;T&gt;</tt> that is covariant on <tt>T</tt> and <tt>B</tt> inherits from <tt>A</tt>, then <tt>CoEntity&lt;B&gt;</tt> inherits from <tt>CoEntity&lt;A&gt;</tt>.</p>
<p>And if there is some <tt>ContraEntity&lt;T&gt;</tt> that is contravariant on <tt>T</tt> and <tt>B</tt> inherits from <tt>A</tt>, then (vice versa) <tt>ContraEntity&lt;A&gt;</tt> inherits from <tt>ContraEntity&lt;B&gt;</tt>.</p>
<p>Co- or contravariance adds some restrictions to corresponding interface or delegate. Covariance is supported in only some cases, and in some other cases is supported contravariance. Let&#8217;s check out what are these restrictions.</p>
<hr />
<h4>Restrictions</h4>
<p>First restriction is that covariance and contravariance issues are available only to delegates and interfaces :).</p>
<p>The second one is that generic type used for co- or contravariance should be a reference type. However generic type is not restricted to be a reference type only. Value type can be used too, but there will be no inheritance relationships for it.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">interface</span> ICovariant<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span> <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw4">interface</span> IInterface <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw4">struct</span> SomeStruct <span class="sy0">:</span> IInterface <span class="br0">&#123;</span> <span class="br0">&#125;</span> <span class="co1">// value type, inherits IInterface</span><br />
<br />
<span class="kw4">class</span> CovariantS <span class="sy0">:</span> ICovariant<span class="sy0">&lt;</span>SomeStruct<span class="sy0">&gt;</span> <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw1">static</span> <span class="kw1">void</span> Main<span class="br0">&#40;</span><span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> args<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; ICovariant<span class="sy0">&lt;</span>SomeStruct<span class="sy0">&gt;</span> covariantS <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CovariantS<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; ICovariant<span class="sy0">&lt;</span>IInterface<span class="sy0">&gt;</span> covariantI <span class="sy0">=</span> covariantS<span class="sy0">;</span> <span class="co1">// compiler error</span><br />
<span class="br0">&#125;</span></div></div>
<p>And the third (and most important one) is following: Type that is to be used for covariance can be used only as type for return values in corresponding interface of delegate. And type that is to be used for contravariance can be used only as type for input parameters in corresponding interface of delegate. (Here and in whole article I mean that using type for setter method is the same as using it as input parameter, and using it for getter method is the same as using it as return value.) Also both covariant and contravariant types cannot be used as types for <tt>ref</tt> (or <tt>out</tt>) parameters.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">delegate</span> T <span class="coMULTI">/* allowed */</span> CovariantProcessor<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; T value <span class="coMULTI">/* not allowed */</span>, <span class="kw1">ref</span> T reference <span class="coMULTI">/* not allowed */</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw4">delegate</span> T <span class="coMULTI">/* not allowed */</span> ContravariantProcessor<span class="sy0">&lt;</span><span class="kw1">in</span> T<span class="sy0">&gt;</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; T value <span class="coMULTI">/* allowed */</span>, <span class="kw1">ref</span> T reference <span class="coMULTI">/* not allowed */</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw4">interface</span> ICovariant<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; T Generate<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// allowed</span><br />
&nbsp; &nbsp; <span class="kw1">void</span> Use<span class="br0">&#40;</span>T value<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// not allowed</span><br />
&nbsp; &nbsp; <span class="kw1">void</span> Change<span class="br0">&#40;</span><span class="kw1">ref</span> T reference<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// not allowed</span><br />
<br />
&nbsp; &nbsp; T Value<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; get<span class="sy0">;</span> <span class="co1">// allowed</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; set<span class="sy0">;</span> <span class="co1">// not allowed</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">interface</span> IContravariant<span class="sy0">&lt;</span><span class="kw1">in</span> T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; T Generate<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// not allowed</span><br />
&nbsp; &nbsp; <span class="kw1">void</span> Use<span class="br0">&#40;</span>T value<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// allowed</span><br />
&nbsp; &nbsp; <span class="kw1">void</span> Change<span class="br0">&#40;</span><span class="kw1">ref</span> T reference<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// not allowed</span><br />
<br />
&nbsp; &nbsp; T Value<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; get<span class="sy0">;</span> <span class="co1">// not allowed</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; set<span class="sy0">;</span> <span class="co1">// allowed</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Without such restrictions we will reach a lot of collisions. It is better to consider an example. Let&#8217;s use a <tt>Mammal</tt>, a <tt>Dog</tt> and a <tt>Cat</tt> as our classes.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">class</span> Mammal <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw4">class</span> Dog <span class="sy0">:</span> Mammal <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw4">class</span> Cat <span class="sy0">:</span> Mammal <span class="br0">&#123;</span> <span class="br0">&#125;</span></div></div>
<p>Now let&#8217;s see what collisions will we reach with covariance that allows input parameters:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">interface</span> ICovariantWrapper<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; T Value <br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; get<span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; set<span class="sy0">;</span> <span class="co1">// not really allowed</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">class</span> Wrapper<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> <span class="sy0">:</span> ICovariantWrapper<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; T Value <span class="br0">&#123;</span> get<span class="sy0">;</span> set<span class="sy0">;</span> <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">static</span> <span class="kw1">void</span> Main<span class="br0">&#40;</span><span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> args<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; ICovariantWrapper<span class="sy0">&lt;</span>Dog<span class="sy0">&gt;</span> wrappedDog <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Wrapper<span class="sy0">&lt;</span>Dog<span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// making wrapped mammal the same as wrapped dog is</span><br />
&nbsp; &nbsp; ICovariantWrapper<span class="sy0">&lt;</span>Mammal<span class="sy0">&gt;</span> wrappedMammal <span class="sy0">=</span> wrappedDog<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// putting a cat into the wrapped dog</span><br />
&nbsp; &nbsp; wrappedMammal.<span class="me1">Value</span> <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Cat<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; Dog dog <span class="sy0">=</span> wrappedDog.<span class="me1">Value</span><span class="sy0">;</span> <span class="co1">// there's really a cat!</span><br />
<span class="br0">&#125;</span></div></div>
<p>The same collision will be in contravariant case. The only difference is that we will first create <tt>IContravariantWrapper&lt;Mammal&gt;</tt> and then cast it to <tt>IContravariantWrapper&lt;Dog&gt;</tt>. After that a <tt>Cat</tt> can be assigned to where a <tt>Dog</tt> should be.</p>
<p>Honestly, the third restriction is more compicated. But we will talk about it at the end of article, when we will better understand what is going on here :)</p>
<p>Knowing the very theory is not enough :) Let&#8217;s check out examples where co- and contravariance are good to be used.</p>
<hr />
<h4>Covariance Example</h4>
<p>We will use interface <tt>ICreator&lt;T&gt;</tt> that is able to create instances of <tt>T</tt> from different sources. Also we will use two classes: <tt>Entity</tt> and it&#8217;s subclass <tt>SerializableEntity</tt>.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">interface</span> ICreator<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; T CreateDefault<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; T CreateFromXDocument<span class="br0">&#40;</span>XDocument xDocument<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; T CreateFromStream<span class="br0">&#40;</span>Stream stream<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw4">class</span> Entity<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw4">class</span> SerializableEntity <span class="sy0">:</span> Entity<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span></div></div>
<p>Now imagine we have class <tt>SerializableEntityCreator</tt> that implements interface <tt>ICreator</tt> for <tt>SerializableEntity</tt>. And also imagine we have class <tt>EntityManager</tt> that needs an instance of <tt>ICreator&lt;Entity&gt;</tt> to work properly.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">class</span> SerializableEntityCreator <span class="sy0">:</span> ICreator<span class="sy0">&lt;</span>SerializableEntity<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw4">class</span> EntityManager<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">public</span> EntityManager<span class="br0">&#40;</span>ICreator<span class="sy0">&lt;</span>Entity<span class="sy0">&gt;</span> entityCreator<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Let&#8217;s now see what we have. On one hand we have <tt>SerializableEntityCreator</tt> that is able to create instances of <tt>SerializableEntity</tt>. It also can create instances of <tt>Entity</tt> because each <tt>SerializableEntity</tt> is an <tt>Entity</tt> too. On other hand we have <tt>EntityManager</tt> that needs something that can create instances of <tt>Entity</tt>. It seems like <tt>SerializableEntityCreator</tt> will match <tt>EntityManager</tt>&#8217;s needs, but without covariance it isn&#8217;t true. And following code will not compile:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace">ICreator<span class="sy0">&lt;</span>SerializableEntity<span class="sy0">&gt;</span> entityCreator <br />
&nbsp; &nbsp; <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SerializableEntityCreator<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
EntityManager manager <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EntityManager<span class="br0">&#40;</span>entityCreator<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// error</span></div></div>
<p>To resolve this issue in C# 2.0/3.0 we need to implement both <tt>ICreator&lt;Entity&gt;</tt> and <tt>ICreator&lt;SerializableEntity&gt;</tt> in <tt>SerializableEntityCreator</tt> class or even create whole new class that will wrap class <tt>SerializableEntityCreator</tt> to implement <tt>ICreator&lt;Entity&gt;</tt> in case when modifications to <tt>SerializanleEntityCreator</tt> are not allowed. But in C# 4.0 this can be fixed just declaring interface covariant – that means adding to declaration <tt>out</tt> keyword before generic param <tt>T</tt>.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">interface</span> ICreator<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span></div></div>
<p>Now <tt>ICreator&lt;T&gt;</tt> is covariant by <tt>T</tt>. That means <tt>SerializableEntityCreator</tt> is not only <tt>ICreator&lt;SerilizableEntity&gt;</tt>, but it is an <tt>ICreator&lt;Entity&gt;</tt> too. And the following code will work:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace">ICreator<span class="sy0">&lt;</span>SerializableEntity<span class="sy0">&gt;</span> entityCreator <br />
&nbsp; &nbsp; <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SerializableEntityCreator<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
EntityManager manager <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EntityManager<span class="br0">&#40;</span>entityCreator<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// success</span></div></div>
<hr />
<h4>Contravariance Example</h4>
<p>Imagine we have: generic delegate <tt>DeblockingProcessor&lt;T&gt;</tt> that is to process any kind of images, some generic interface <tt>IImageSequence&lt;T&gt;</tt> that uses this delegate and a class <tt>BitmapSequence</tt> that implements our interface for a concrete image type – <tt>Bitmap</tt>:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> DeblockingProcessor<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span><span class="br0">&#40;</span>T image, <span class="kw4">int</span> level<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw1">public</span> <span class="kw4">interface</span> IImageSequence<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">void</span> DeblockAll<span class="br0">&#40;</span>DeblockingProcessor<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> deblocker<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw4">class</span> BitmapSequence <span class="sy0">:</span> IImageSequence<span class="sy0">&lt;</span>Bitmap<span class="sy0">&gt;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">void</span> DeblockAll<span class="br0">&#40;</span>DeblockingProcessor<span class="sy0">&lt;</span>Bitmap<span class="sy0">&gt;</span> deblocker<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Now if we have some deblocking processor that works for <tt>Image</tt> type, we might want to use it with <tt>BitmapSequence</tt> (<tt>Image</tt> is a superclass for <tt>Bitmap</tt>). Unfortunately in C# 3.0 following code would not compile:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace">BitmapSequence bitmaps <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> BitmapSequence<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
DeblockingProcessor<span class="sy0">&lt;</span>Image<span class="sy0">&gt;</span> imageDeblocker <span class="sy0">=</span> <span class="co1">// getting some deblocker</span><br />
&nbsp; &nbsp; ProcessorsFactory.<span class="me1">Instance</span>.<span class="me1">GetDeblockingProcessor</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
bitmaps.<span class="me1">DeblockAll</span><span class="br0">&#40;</span>imageDeblocker<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// compiler error</span></div></div>
<p>In C# 3.0/2.0 we cannot directly pass <tt>DeblockingProcessor&lt;Image&gt;</tt> as a param to a method that needs <tt>DeblockingProcessor&lt;Bitmap&gt;</tt> (because one cannot be directly casted to other). Solution is to wrap existent delegate with an anonymous one that has needed signature (and is of type <tt>DeblockingProcessor&lt;Bitmap&gt;</tt>):</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace">bitmaps.<span class="me1">DeblockAll</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="br0">&#40;</span>Bitmap image, <span class="kw4">int</span> level<span class="br0">&#41;</span> <span class="sy0">=&gt;</span> imageDeblocker.<span class="me1">Invoke</span><span class="br0">&#40;</span>image, level<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>In C# 4.0 this may be easily fixed making delegate contravariant on <tt>T</tt> by adding <tt>in</tt> keyword to it&#8217;s declaration:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> DeblockingProcessor<span class="sy0">&lt;</span><span class="kw1">in</span> T<span class="sy0">&gt;</span><span class="br0">&#40;</span>T image, <span class="kw4">int</span> level<span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>After this change <tt>DeblockingProcessor&lt;Image&gt;</tt> can be casted to <tt>DeblockingProcessor&lt;Bitmap&gt;</tt> and the following code will work:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace">bitmaps.<span class="me1">DeblockAll</span><span class="br0">&#40;</span>imageDeblocker<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// success</span></div></div>
<p>As we can see from this example, in C# 2.0/3.0 we are able to use anonymous delegates instead of contravariance. But if we&#8217;ll have interface passed as a param instead of delegate (some <tt>IDeblockingProcessor&lt;T&gt;</tt>, that is needed to perform series of calls like <tt>Prepare(T image)</tt>, <tt>Start()</tt>, <tt>Clean()</tt>, etc.), then contravariance is very useful, because we have no anonymous interfaces in .NET.</p>
<hr />
<h4>Covariance and Contravariance in C# 2.0/3.0</h4>
<p>It should be noted that C# 2.0/3.0 already supports some way of covariance and contravariance in delegates. It is when we&#8217;re creating new delegate from a method (in many cases we do not code it – it&#8217;s performed automatically). Delegate constructor can take as a param not only a method with same signature, but with signature that is co- or contravariative to delegate&#8217;s. And it works not only for delegates with generic types, but for all delegates (the only exception is for <tt>ref</tt> parameters).</p>
<p>It is easy enough to understand this with examples. We will use <tt>XNode</tt> and <tt>XElement</tt>, where <tt>XElement</tt> is a subclass of <tt>XNode</tt> (between them is also <tt>XContainer</tt>, but it is not so often used). Let&#8217;s define following delegates and methods.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> XElementCacher<span class="br0">&#40;</span>XElement xElement<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">public</span> <span class="kw4">delegate</span> XNode XNodeGenerator<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">public</span> <span class="kw4">delegate</span> XNode XObjectCopier<span class="br0">&#40;</span>XElement xElement<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">void</span> CacheXNode<span class="br0">&#40;</span>XNode xNode<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw1">static</span> XElement GenerateXElement<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw1">public</span> <span class="kw1">static</span> XElement CopyXNode2XElement<span class="br0">&#40;</span>XNode xNode<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* ... */</span><br />
<span class="br0">&#125;</span></div></div>
<p>As we can see, none of the methods&#8217; signature corresponds to any of delegates&#8217; signatures. However, following assignments are all correct:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// contravariance</span><br />
XElementCacher xElementCacher <span class="sy0">=</span> CacheXNode<span class="sy0">;</span><br />
<br />
<span class="co1">// covariance</span><br />
XNodeGenerator xNodeGenerator <span class="sy0">=</span> GenerateXElement<span class="sy0">;</span><br />
<br />
<span class="co1">// mixed - tricky one, heh :)</span><br />
XObjectCopier xElement2NodeCopier <span class="sy0">=</span> CopyXNode2XElement<span class="sy0">;</span><br />
<br />
<span class="co1">// and here is what really happens</span><br />
xElementCacher <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> XElementCacher<span class="br0">&#40;</span>CacheXNode<span class="br0">&#41;</span><span class="sy0">;</span><br />
xNodeGenerator <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> XNodeGenerator<span class="br0">&#40;</span>GenerateXElement<span class="br0">&#41;</span><span class="sy0">;</span><br />
xObjectCopier <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> XObjectCopier<span class="br0">&#40;</span>CopyXNode2XElement<span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>As I said, this works for delegates with generic types too. So if we are creating delegates directly from methods (not using delegates created somewhere else, as I&#8217;ve done in my example), then we do not need to extend delegate declaration with <tt>in</tt>/<tt>out</tt> modifiers – covariance and contravariance in such case are already supported.</p>
<hr />
<h4>More About Third Restriction</h4>
<p>Most of the sources are talking about this restriction in simplified manner: <tt>T</tt> can be used only for return values in covariant types, and <tt>T</tt> can be used only for input parameters in contravariant types. I&#8217;ve already described why. But now I&#8217;ll tell you more: in covariant types under some circustances <tt>T</tt> can be used for input parameters! And in contravariant types <tt>T</tt> can be used for return values!</p>
<p>Here are the full rules on how generic type <tt>T</tt> can be used in covariant interface/delegate:</p>
<ul>
<li>all ref/out parameters should be independent on <tt>T</tt>;</li>
<li>all input parameters should be contravariant on <tt>T</tt> (or independent on <tt>T</tt>);</li>
<li>all return values should be covariant on <tt>T</tt> (or independent on <tt>T</tt>).</li>
</ul>
<p>And these are for contravariant (on <tt>T</tt>) interface/delegate:</p>
<ul>
<li>all ref/out parameters should be independent on <tt>T</tt>;</li>
<li>all input parameters should be covariant on <tt>T</tt> (or independent on <tt>T</tt>);</li>
<li>all return values should be contravariant on <tt>T</tt> (or independent on <tt>T</tt>).</li>
</ul>
<p>As <tt>T</tt> is always covariant on itself, the usual version of the third restriction is just a particular case of full rules.</p>
<p>Following is simple example that shows how it works. Let&#8217;s declare two types that are co- and contravariant on <tt>T</tt>.</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">interface</span> ICovariant<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span> <span class="br0">&#123;</span> <span class="br0">&#125;</span><br />
<br />
<span class="kw4">interface</span> IContravariant<span class="sy0">&lt;</span><span class="kw1">in</span> T<span class="sy0">&gt;</span> <span class="br0">&#123;</span> <span class="br0">&#125;</span></div></div>
<p>Using power of full rules :) following delegates will work perfectly as covariant and contravariant:</p>
<div class="codecolorer-container csharp twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="csharp codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw4">delegate</span> ICovariant<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> CovariantHandler<span class="sy0">&lt;</span><span class="kw1">out</span> T<span class="sy0">&gt;</span><span class="br0">&#40;</span>IContravariant<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> x<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw4">delegate</span> IContravariant<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> ContravariantHandler<span class="sy0">&lt;</span><span class="kw1">in</span> T<span class="sy0">&gt;</span><span class="br0">&#40;</span>ICovariant<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> x<span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<hr />
<h4>Conclusion</h4>
<p>I must appreciate that development of sophisticated program architecture is going to be a bit easier having covariant generic collections (not only <tt>ConvertAll</tt> method). Sure it is an opened question how to put elements into such collection correctly, because generic type cannot be used for input if we wonna to have it for covariance. However, interfaces have a large range of usage, and covariance is a good new feature for them.</p>
<p>But, talking about delegates, new abilities, as for me, is not a big breakthrough. That is because in some cases covariance and contravariance are already supported by previous versions of C#, and in other cases we can use anonymous delegates to emulate them.</p>
<p>Also I recommend to investigate hidden problems that may probably occur after enabling co- or contravariance for a widely used type. As a start point Eric Lippert&#8217;s article <a href="http://blogs.msdn.com/ericlippert/archive/2007/11/02/covariance-and-contravariance-in-c-part-nine-breaking-changes.aspx" target="_blank">Breaking Changes</a> can be used.</p>
<p><b>P.S.</b> Covariance and contravariance are supported by IL since very 2.0 version of .NET Framework. We can think of this in two ways - great abilities of IL or limitations of C# :)</p>
<p><b>P.P.S.</b> Thanks to <a href="http://www.bezzub.com" target="_blank">Andrew Bezzub</a> for his comments on this article during it&#8217;s creation :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/dot-net/2009/c-sharp-4-covariance-and-contravariance/feed</wfw:commentRss>
		</item>
		<item>
		<title>New Series of Posts Coming</title>
		<link>http://blog.T-L-K.com/misc/2009/new-series-of-posts-coming</link>
		<comments>http://blog.T-L-K.com/misc/2009/new-series-of-posts-coming#comments</comments>
		<pubDate>Wed, 01 Apr 2009 23:08:05 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=113</guid>
		<description><![CDATA[My trial period at the new work is going to be finished, and it seems like I&#8217;ll have enough time for new articles. During period on innactivity I found that somebody really reads my stuff (not my friends only). At least Jens Krause wrote in his blog that he&#8217;d found my article about RSS parsing helpful.
Unfortunately [...]]]></description>
			<content:encoded><![CDATA[<p>My trial period at the new work is going to be finished, and it seems like I&#8217;ll have enough time for new articles. During period on innactivity I found that somebody really reads my stuff (not my friends only). At least Jens Krause <a href="http://www.websector.de/blog/2009/01/25/quick-tip-objective-c-formatting-an-rfc2822-date-of-an-rss-feed-using-nsdateformatter/" target="_blank">wrote in his blog</a> that he&#8217;d found my article about RSS parsing helpful.</p>
<p>Unfortunately (or fortunately) I no longer work with iPhones and <span style="white-space: nowrap">Objective-C</span> development. Currently I returned back to use .NET technologies, but now in context of web development. So my new topics will cover some of corresponding issues, and hope they&#8217;ll be interesting :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/misc/2009/new-series-of-posts-coming/feed</wfw:commentRss>
		</item>
		<item>
		<title>Top 25 Programming Errors</title>
		<link>http://blog.T-L-K.com/misc/2009/top-25-programming-errors</link>
		<comments>http://blog.T-L-K.com/misc/2009/top-25-programming-errors#comments</comments>
		<pubDate>Sun, 18 Jan 2009 20:49:33 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[errors]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=105</guid>
		<description><![CDATA[Have just reached a list of top 25 most dangerous programming errors that was released by cyber security experts a week ago. An important one, I think :) And with this list are provided resources and solutions to be used to eliminate these errors if they&#8217;re present. Also seems like this list is to be [...]]]></description>
			<content:encoded><![CDATA[<p>Have just reached a list of top 25 most dangerous programming errors that was released by cyber security experts a week ago. An important one, I think :) And with this list are provided resources and solutions to be used to eliminate these errors if they&#8217;re present. Also seems like this list is to be used for code certifications and for software testing tools. But first of all it should be used by us, developers :)</p>
<p>Here is the list: <a href="http://www.sans.org/top25errors/#s4" target="_blank">http://www.sans.org/top25errors</a></p>
<p>I hope, in 2020 all these errors will be studied only at programming history lessons :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/misc/2009/top-25-programming-errors/feed</wfw:commentRss>
		</item>
		<item>
		<title>Parse Date from RSS to NSDate</title>
		<link>http://blog.T-L-K.com/i-phone/2008/parse-date-from-rss</link>
		<comments>http://blog.T-L-K.com/i-phone/2008/parse-date-from-rss#comments</comments>
		<pubDate>Fri, 26 Dec 2008 18:01:41 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=50</guid>
		<description><![CDATA[Today I&#8217;ll show how to parse date from RSS feed to NSDate in iPhone application.
When processing several RSS feeds, it is usual task to arrange and sort them by date. Therefore text representation of date need to be transformed to NSDate.
My googling of solutions for this issue resulted in use of [NSCalendarDate dateWithNaturalLanguageString:string] function. As I [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ll show how to parse date from RSS feed to <tt>NSDate</tt> in iPhone application.</p>
<p>When processing several RSS feeds, it is usual task to arrange and sort them by date. Therefore text representation of date need to be transformed to <tt>NSDate</tt>.</p>
<p>My googling of solutions for this issue resulted in use of <tt>[NSCalendarDate dateWithNaturalLanguageString:string]</tt> function. As I <a href="/i-phone/2008/iphone-simulator-looks-confusing" target="_self">wrote before</a>, <tt>NSCalendarDate</tt> is not supported under iPhone OS, so this way lacks.</p>
<p>Another way is to parse date via <tt>NSDateFormatter</tt>, but I didn&#8217;t find any full solution. So let&#8217;s write it :)</p>
<p><span id="more-50"></span>Usually RSS date is stored in following format: <tt>@&#8221;Fri, 12 Dec 2008 18:45:15 -0800&#8243;</tt> (to learn more about RSS spec, use this resource: <a href="http://cyber.law.harvard.edu/rss/rss.html" target="_blank">RSS 2.0 Specification</a>). In date formatter terms it can be written as <tt>@&#8221;EEE, d MMM yyyy HH:mm:ss Z&#8221;</tt>. Knowing that, it is easy to write result code. Here it is:</p>
<div class="codecolorer-container objc twitlight" style="overflow:auto;white-space:nowrap;width:595px"><div class="objc codecolorer" style="font-family:Monaco,Lucida Console,monospace"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span class="kw5">NSString</span></a> <span class="sy0">*</span><span class="kw4">string</span> <span class="sy0">=</span> <span class="co3">@</span><span class="st0">&quot;Fri, 12 Dec 2008 18:45:15 -0800&quot;</span>;<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/"><span class="kw5">NSDateFormatter</span></a> <span class="sy0">*</span>dateFormatter <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/"><span class="kw5">NSDateFormatter</span></a> alloc<span class="br0">&#93;</span> init<span class="br0">&#93;</span>;<br />
<span class="br0">&#91;</span>dateFormatter setDateFormat<span class="sy0">:</span><span class="co3">@</span><span class="st0">&quot;EEE, d MMM yyyy HH:mm:ss Z&quot;</span><span class="br0">&#93;</span>;<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span class="kw5">NSDate</span></a> <span class="sy0">*</span>date <span class="sy0">=</span> <span class="br0">&#91;</span>dateFormatter dateFromString<span class="sy0">:</span><span class="kw4">string</span><span class="br0">&#93;</span>;<br />
<span class="co2">// if (date == nil) { } - uncomment this if you want to handle failures</span><br />
<span class="br0">&#91;</span>dateFormatter release<span class="br0">&#93;</span>;</div></div>
<p>I&#8217;m not sure this covers all of situations, but it is a good point to start from :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/i-phone/2008/parse-date-from-rss/feed</wfw:commentRss>
		</item>
		<item>
		<title>Apple Mac Tini</title>
		<link>http://blog.T-L-K.com/misc/2008/apple-mac-tini</link>
		<comments>http://blog.T-L-K.com/misc/2008/apple-mac-tini#comments</comments>
		<pubDate>Fri, 26 Dec 2008 11:40:43 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[Apple]]></category>

		<category><![CDATA[joke]]></category>

		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=71</guid>
		<description><![CDATA[Funny joke about Apple products :)

]]></description>
			<content:encoded><![CDATA[<p>Funny joke about Apple products :)</p>
<p style="text-align: center;"><object width="480" height="295" data="http://www.youtube.com/v/noe3kR8KqJc&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/noe3kR8KqJc&amp;hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/misc/2008/apple-mac-tini/feed</wfw:commentRss>
		</item>
		<item>
		<title>iPhone Simulator Looks Confusing</title>
		<link>http://blog.T-L-K.com/i-phone/2008/iphone-simulator-looks-confusing</link>
		<comments>http://blog.T-L-K.com/i-phone/2008/iphone-simulator-looks-confusing#comments</comments>
		<pubDate>Wed, 24 Dec 2008 15:18:31 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[Objective-C]]></category>

		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=35</guid>
		<description><![CDATA[A week ago I found some annoying thing about iPhone OS and iPhone simulator. As a result you cannot be really sure that application that works great on simulator whould even be compiled for device.
Unpretty thing that I found is that NSCalendarDate and NSURLDownload classes are not supported on iPhone OS. But they are do supported on [...]]]></description>
			<content:encoded><![CDATA[<p>A week ago I found some annoying thing about iPhone OS and iPhone simulator. As a result you cannot be really sure that application that works great on simulator whould even be compiled for device.</p>
<p>Unpretty thing that I found is that <tt>NSCalendarDate</tt> and <tt>NSURLDownload</tt> classes are not supported on iPhone OS. But they are do supported on simulator! Code is not compiled in device mode with error that class is unknown. Seems to be a simulator bug :(</p>
<p>Please, be careful, and do not use <tt>NSCalendarDate</tt> and <tt>NSURLDownload</tt>. Also test your application on a device regularly. If you do not have a device, just build your app (<em>Cmd-B</em>) in device mode, to be sure it is successfully compiled.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/i-phone/2008/iphone-simulator-looks-confusing/feed</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa Memory Management – Simple Rules</title>
		<link>http://blog.T-L-K.com/i-phone/2008/cocoa-memory-management</link>
		<comments>http://blog.T-L-K.com/i-phone/2008/cocoa-memory-management#comments</comments>
		<pubDate>Tue, 23 Dec 2008 07:44:55 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[memory]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=22</guid>
		<description><![CDATA[Few month ago I started to develop iPhone application for a new customer. Having a lot of .NET experience before (and no Objective-C experience), I was discouraged with absence of garbage collector. Yep, garbage collection is unfortunately not supported under iPhone OS, it is supported only under Mac OS X. Dealing with manual memory allocation/deallocation, releasing/retaining/autoreleasing took time [...]]]></description>
			<content:encoded><![CDATA[<p>Few month ago I started to develop iPhone application for a new customer. Having a lot of .NET experience before (and no Objective-C experience), I was discouraged with absence of garbage collector. Yep, garbage collection is unfortunately not supported under iPhone OS, it is supported only under Mac OS X. Dealing with manual memory allocation/deallocation, releasing/retaining/autoreleasing took time in researches until I&#8217;ve reached a good article at <a href="http://www.stepwise.com/" target="_blank">stepwise.com</a>. In a bit of information are described common memory management rules and common mistakes. Here it is:</p>
<p><a href="http://www.stepwise.com/Articles/Technical/2001-03-11.01.html" target="_blank">Very simple rules for memory management in Cocoa</a></p>
<p>For more information please use Apple document <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/index.html" target="_blank">Memory Management Programming Guide for Cocoa</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/i-phone/2008/cocoa-memory-management/feed</wfw:commentRss>
		</item>
		<item>
		<title>Hello! :)</title>
		<link>http://blog.T-L-K.com/misc/2008/hello-world</link>
		<comments>http://blog.T-L-K.com/misc/2008/hello-world#comments</comments>
		<pubDate>Mon, 22 Dec 2008 11:41:55 +0000</pubDate>
		<dc:creator>TLK</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.T-L-K.com/?p=4</guid>
		<description><![CDATA[Hi, everybody!
I decided to start my own blog :) The reason why is because on my latest project I was need to search answers to my questions over the internet, and many answers were found in blogs. So, I thought, it is a goog idea to share my own knowledge and experience with whole world IT community.
So [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, everybody!</p>
<p>I decided to start my own blog :) The reason why is because on my latest project I was need to search answers to my questions over the internet, and many answers were found in blogs. So, I thought, it is a goog idea to share my own knowledge and experience with whole world IT community.</p>
<p>So let&#8217;s start and I hope somebody finds my posts helpful :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.T-L-K.com/misc/2008/hello-world/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
