C# 4.0 Features Announced

   The big news (actually the big news was Windows Azure but I care more about C# 4.0) from yesterday is that Anders (Hallowed be his name) has spoken. The future of C# have been announced. I bet that many of you mortals are eagerly awaiting my interpretation of the words of the Prophet.

   1. Dynamic Lookup. (not to be confused with dynamic typing)

   This feature seems similar to Visual Basic's VARIANT type. Declaring a variable (also fields, return types, etc.) as "dynamic" means that the compiler does not make compile time checks for this variable. Instead it encodes the information in the compiled code and lookup for methods and properties is performed at runtime. Note that unlike dynamically typed languages you cannot enhance the type at runtime. This feature is used solely to allow C# to interoperate with dynamic environments and not to make C# dynamically typed language. Conversion between the "dynamic" type and any other type is implicit in both directions. You can use objects of "dynamic" type just like any other object.

   dynamic d = GetDynamicObject(…);
   d.M(7); // calling methods
   d.f = d.P; // getting and settings fields and properties
   d["one"] = d["two"]; // getting and setting thorugh indexers
   int i = d + 3; // calling operators
   string s = d(5,7); // invoking as a delegate

You may wonder how this is achieved. It depends on the real type of the dynamic object.
   a) if the object is a COM object operations are performed through IDispatch interface.
   b) if the object implements the IDynamicObject interface this means that the object defines its own operations. The object is "asked" how the operations should be performed. This makes use of the infamous Dynamic Language Runtime and is how type systems of IronPython and IronRuby are implemented.
   c) if the object is plain C# object lookup is performed at runtime through reflection and methods are called through reflection. This means that from now on we will have really sweet reflection. Just load the type and call the methods. No need for MethodInfo class, no need to prepare collections of parameters, invoking delegates, etc. The runtime and the compiler will do it for you.

   The bad news is that you cannot use extension methods and lambda expressions so no LINQ for your dynamic objects. Sorry!

   2. Named and Optional Parameters.

   Remember C++'s default values for function parameters that made the parameter in question optional? In C# 4.0 you will be able to do that. If you have used COM in C# you have probably called methods with 15+ arguments when you only need to pass 3. It was not that COM designers were that stupid. They just made most of the parameters optional but C# did not support that so we had to call the method with the full list of parameters. Also use the next two years to write pointless overloads to methods just to pass some default values for parameters because after that you will not have any excuse to do so. How to do it:

   public void M(int x, int y = 5, int z = 7);

As far as I remember this is the same as in C++. Just give the value. How to call it:

   M(1, 2, 3); // ordinary call of M
   M(1, 2); // omitting z – equivalent to M(1, 2, 7)
   M(1); // omitting both y and z – equivalent to M(1, 5, 7)

Named parameters allow you to pass arguments by parameter name. That way you can skip parameters and reorder them in the method call:

   M(1, z: 3); // passing z by name
   M(x: 1, z: 3); // passing both x and z by name
   M(z: 3, x: 1); // reversing the order of arguments

   Optional parameters can also be used with indexers and constructors. Arguments are evaluated in the order they appear in the method call. When deciding on overloads the compiler prefers methods that will make a full method call to those that must use optional parameters. Example:

   signatures:
   M(int i, string s = "Hello")
   M(int i)

   call:
   M(5);

In this case M(int i) will be preferred to M(int i, string s = "Hello") because the latter requires the use of default values.

   One problem I can see with this is that if you have two methods with compatible signatures like the above you can remove the M(int i) method and you will not get compile time error for the call because it will resort to the other overload. However this is not really new because if we had a method that accepted object argument and removed the int argument method we would have the same problem today in C# 1.0/2.0/3.0. When we switch to C# 4.0 we need to keep in mind that it might happen more often.

   3. COM interop

   I am not experienced in COM so I am not really sure how COM related features work. What I understand is that COM types are now mapped to C# types. VARIANT is mapped to "dynamic" so the amount of casting needed is greatly reduced. Previously most COM types were mapped to object and although types were often known a lot of casting was required. Except for being able to use default argument values in method calls you can also omit "ref" for parameters of COM methods. Anders (Hallowed be his name) says that you can now compile without PIA but I do not know what PIA is so I will not  try to interpret this.

   4. Variance

   I do not feel prepared to explain what variance is so you may want to check the Wikipedia article. Very simple explanation is that situations where you can "replace" a type with its parent type are covariant and situations where you can "replace" a type with a child type are contravariant. Lets move to the examples:

   IList<string> strings = new List<string>();
   IList<object> objects = strings;

This will not compile in C# for a very good reason. While you can get objects from the List<string> you cannot add an object to the list unless it is a string. If this was allowed we would get runtime exception when we tried to add some non-string object. However there are many interfaces that do not need to add objects. What if instead of IList<T> we used IEnumerable<T> ?

With C# 4.0 you can define the IEnumerable<T> interface as covariant for T like this:

   public interface IEnumerable<out T> : IEnumerable
   {
       IEnumerator<T> GetEnumerator();
   }
   public interface IEnumerator<out T> : IEnumerator
   {
       bool MoveNext();
       T Current { get; }
   }

The "out" keyword informs the compiler that it is safe to allow the T type to be "replaced" with parent type. It also makes the compiler check that T is only output (returned) from this interface. If we had defined the IList interface like this we would get compile time error because there is an input (method parameters or property assignments) of the T type. Due to this change we will be able to use extension method defined on IEnumerable<object> on IEnumerable<string>. That opens many more opportunities for LINQ queries.

   The other side of the coin is contravariance. Consider the interface IComparer<T>. It accepts input of T but does not output T (returns int). It makes sense for IComparer<object> to be accepted where IComparer<string> is expected because it can in fact compare strings. In C# 4.0 IComparer<T> can be defined like this:

   public interface IComparer<in T>
   {
       public int Compare(T left, T right);
   }

The "in" modifier instructs the compiler to enforce that T is not output and allows it to "replace" T with child type when used.

   A generic type can have both "in" and "out" modifiers on its generic parameters. Consider the delegate type Func (heavily used in LINQ):

   public delegate TResult Func<in TArg, out TResult>(TArg arg);

I believe this example illustrates best how you can use variance features. Mark arguments as "in" and results as "out". In this case Func<object, string> can be used where Func<string, object> is expected.

   Unfortunately there are some limitations. You cannot use variance with classes and methods only with interfaces and delegates. Also you cannot use it on value types. Only reference conversions are allowed. There are restrictions in the CLR they say :(

   From my point of view it seems that C# 4.0 is the version that affects the way we program C# the less compared with previous versions. C# 2.0 added generics, C# 3.0 added LINQ and we do not get anything fundamental with C# 4.0. We will not change our style of coding because of the new features like we did with previous versions. Maybe for people coding COM it will be a big change but for the rest of us it will not be that special. After all we will not use variance every day. On the other hand it seems that there is a fair amount of developers that develop COM and Office applications and plugins. For them C# 4.0 will be Google given. I personally miss language level support for immutable types. People are talking about get only automatic properties with constructor or initializer support for them. I also imagine that we could declare types as immutable and the compiler can enforce that there are no mutators and also allow such types to be defined as "const". Let alone the optimizations that the CLR can do on such types. However C# 4.0 will definitely make the language better and it seems like the pseudo-dynamic type is a lot of work on the compiler and the design side even if it is not such a big deal for developers that do not need to work with dynamic systems. What is more we do not know if IronPython and IronRuby will get big. If they do dynamic will save us from a lot of ugly code needed to interop with them. Also remember that this is all a subject to change.

You can find more info in this document that I used as a reference and also copied the examples from.
Tags:   english programming 
Posted by:   Stilgar
04:49 29.10.2008

Comments:

First Previous 1 Next Last 

Posted by   JOKe (Unregistered)   on   16:34 30.10.2008

Mnooo me kefi kak C# staa super boza :D
microsoft znaqt li che C# e ezik a ne produkt ?
che te kato produkt gi vkarvat featurite :T
i to poveche features vkartvat v C# otkolkoto v windows dea :D
mnoo qko :D

Posted by   Stilgar   on   16:40 30.10.2008

na men sa mi malko novite features
iskam OSHTEEEEE
puk neka mi e bozavo

Posted by   JOKe (Unregistered)   on   19:30 30.10.2008

em neka neka te iskat da go napraat Dynamic language ama neka :D  
http://weblogs.asp.net/okloeten/archive/2008/10/29/6708812.aspx

Posted by   Stilgar   on   20:05 30.10.2008

Pfu tva tolkova da ne razbirash kvo pravi dynamic... NISHTO dinamichno ne slagat v C#! Puk predlojenieto mu e tolkova absurdno, che niamam dumi. Po negovia nachin mu pojelavam uspeh kato reshi da govori s JavaScript...

A ne znam kak niakoi na sveta moje da ima neshto protiv optional parameters.
"most people will just get either confused by all the syntax"
Spored men CHAK takiva glupaci ne triabva da im se razreshava da pishat kod. Ako edin syntaxis ne moje da nauchish po-dobre ne prechi.

I osven tova polzvam anonimni delegati redovno.

Abe to toia e iasno, che e nekadurnik za tova ABSOLUTNO VUV VSEKI KOMENTAR GO NALIVAT!

Posted by   JOKe (Unregistered)   on   15:14 31.10.2008

vij sq batka :)
vaprosa e che C# ne e Windows.
kakvo iskam da kaja
Windows e OS
OS e za da svyrje hardware-a s NAS potrebitelite.
kvo se poluchava obache
Windows ne samo ne e OS mi e boza veche shtoto triia si kupish specialen hardware za da ti vyrvi Vista i nemoje da si q polzvash na starite PC-ta ami i ima features deto NIKOI NEISKA az iskam da moga prosto da si pusna Voodoo 1nicata na neq.

C# e sashtata hava
Ezika za programirane e za da mojesh po maximalno lesen nachin da syzdadesh maximalno mnogo neshta oki da kajem ezicite za obshto prednaznachenei t.e. edno vreme tova sa bili stekove opashki  strukturite sq ne e iasno kakvo e
neznam do kolko e ideq da ima 1020112012012 nachina da napraish 1 neshto


kakto i da e vehce se radvam che sam javar :D

Posted by   Stilgar   on   15:29 31.10.2008

Az puk silno jelaeh da mi slojat search vuv Vistata i niamam Voodoo 1 (imam 8800GT). To po taia logika niama absolutno nikva prichina da praviat drug Windows sled 98.

Moje da ima mnogo nachini da napravish edno neshto (to tva e neizbejno s vseki ezik), no ima EDIN pravilen i toi e slojen kato feature v ezika.

Mi radvai se che si javar. Like anyone cares:) Az se radvam, che ne sum i che pisha na ezik deto ne sedi tam kudeto e bil predi 10 godini i mi ulesniava jivota. I umiram ot kef da pravia neshta s wizardi i drag&drop (bez maitap). Osven tva silno se nadiavam da ne pisha cial jivot na C# i da imam volia edin den da zaeba backgrounda i da mina na sledvashtia cool ezik bil toi Python, F#, Scala ili kakvoto i da e.

Posted by   mkmurray (Unregistered)   on   02:01 21.11.2008

PIA = Primary Interop Assemblies

See this MSDN article:  http://msdn.microsoft.com/en-us/library/aax7sdch.aspx

Posted by   Guest (Unregistered)   on   20:22 26.02.2011

Stilgar,

(Spitting at your feet and bowing) Explanations for covariant / contravariant just never clicked with me, I was like "out", "in" etc keyword?  I kept coming back to the subject a few times...no clicking, even Jon Skeets book I sort of skipped through it wondering what was wrong with me.  Now it makes sense, had a "duh" moment, your simple explanation drove it home.  Thanks!

Posted by   Stilgar   on   20:53 26.02.2011

I've always wondered if it makes sense to write about things that more clever people are going to write about. I usually avoid it but sometimes reason that one more resouce might help on a particular topic. Comments like this make me happy that my judgement is in fact correct.

Posted by   JOKe (Unregistered)   on   16:04 21.01.2013

chak sega osaznavam 4ta to4ka :) mnogo polezno mersaj :D

First Previous 1 Next Last 


Post as:



Post a comment: