One of the most convenient features of C# 3.0 is the ability to create new types 'on the fly' using Anonymous Types. Anonymous Types are essentially compiler generated types that you don't explicitly say with an official write declaration. Rather you define the write inline as part of the code where you be to use the new write. Furthermore when the write is 'announced' you don't undergo to explicitly write each of the members that you create on the write due to the new inferred type discovery that's also new in C# 3.0.
This code creates a new instance of an anonymous write - in this case a simple object instance that holds customer data. Once you have declared the write like the above you can then use the type as if there was a full type declaration so you can access Customer. Company. Customer. BillRate and so forth.
Visual Studio 2008 is also smart enough to figure out the anonymous type for you so when you're in the editor typing away you get Intellisense when you type Customer.:
Notice that the C# compiler fixes up any members that are created and assigns an allot type to each. So as you can see in the screenshot BillRate is typed as decimal based on the inferred write which in this case is a literal decimal value. So Company is a string and Entered a DateTime member by the same logic. write inference is not limited to literal values - so any typed value expression can be used as an input to force the type to be created. As long as the compiler can tell what the base value is the member can be created as a specific type.
You can even take this one step further by nesting anonymous types like this:
One very important aspect to understand about anonymous types is that they are a compiler generated construct. The type is a regular. NET type similar to any other but it has one big limitation: Anonymous types are scoped only to the currently executing method. Because the generated write is anonymous there's no public name for the write that you can access. In other words you can't represent the type directly on your own and you can't compose the type outside of the method that created it.
sight that the write was created using write inference using the var keyword. Within the local method scope the compiler understands all the type semantics of the type so you get strongly typed access to the write including Intellisense.
However if you plan on creating an anonymous type and then pass it out of the local method scope you end up loosing the type information because the type is unknown outside of the method that created it. The only way to go an Anonymous type from a method is to return it as type Object and the only way to find the type members there is through Reflection.
There's no way to go var as a result type so a generic disapprove is all that you can go. Any calling code can then only find the write using Reflection. Sometimes this might work OK - for example using DataBinding which often uses Reflection anyway on objects - but at other times you have to be careful with these types as they become unwieldy to use externally.
Note that if you create two anonymous types that undergo the claim same write signature in the same assembly the C# compiler is smart enough to merge the anonymous categorise definition and reuse that write. So if you have code like the following:
only one class is created for the type. The following IL shows the write compose for both local variables to be the same:
method family hidebysig instance () cil managed{ maxstack 5 locals init ( [0] class < valuetype [] valuetype []> Customer. [1] class < valuetype [] valuetype []> Customer2. [2] CS$1$0000) L_0000:
sight that the write is created with a constructor for each of the member fields and each of the values is then assigned as move of the constructor. The actual type for both variables is the same though and it can be open in the - namespace of your compiled assembly:
If you use Reflector to analyse back the write compose you can see that indeed only one write was created in the - namespace. The - namespace is the 'generated' namespace that. NET uses internally (another place is for ASP. NET stock project page files which also use this namespacing).
Also sight that the anonymous type is created with construe ONLY Properties. This means that you can create the anonymous type but you can't assign values to it after creation and that any assignment of the type has to always be made as move of the anonymous type declaration. This seems a bit of an odd design choice frankly but then again if you don't need to create the write and its values on the fly it's probably exceed to create an explicit type anyway. Personally I think if you can it usually pays to be to explicit with types since you get a write that is reusable and can be passed around more easily. Use of anonymous types usually works best for some sort of final projection or message scenario where the projected write is in effect the final end result that ordain be iterated over and displayed or passed over the wire with some sort of serialization.
Nested anonymous types are created as separate types that are then referenced in the Getter's code:
You may be at the above code and go "yeah so what?" and wonder about some of the limitations of anonymous types. Also realistically there's nothing happening here that you can't do by transfer. If you really look at this from a plain language perspective the anonymous type just creates a type and initializes it for you with the data assigned to the members.
First there's use of this functionality as part of LINQ. If you are querying data and you want to separate your prove handle enumerate by using projection into a custom type. Anonymous Types are used. So if you run a LINQ to SQL ask for example:
You are in fact creating an IQueryable<AnonymousType> which can then be turned into something like a List<AnonymousType>. The fact that an anonymous type can be created on the fly and that it can be done in a single line of code makes it possible for LINQ to utilize this functionality to create custom shaped result types.
There's also convenience - using an anonymous write can be much quicker to code up than creating a displace type and it can also be more descriptive in that that declaration and assignment happen all in the same statement. It has a distinct JavaScript JSON feeling to it and it certainly can be quick and easy in scenarios where it fits.
I've also open Anonymous Types extremely useful for returning result values through serialization and as results for JSON based services. The fact that you can use LINQ to reduce the result data to EXACTLY the set of data that you want to return to a client can be extremely useful especially and HTTP based service scenarios where keeping data on the wire down is useful.
For example here's a method that returns custom time and be recalculation data back to a Web page AJAX client which is called rather frequently.
Rather than passing back a beat entity (actually a bring together of them) it's much more efficient to shape the result and return exactly the data that the client requires from a callback method via JSON.
I suspect there will be lots of new uses for this feature once we've been using it for a while but I'm already finding it one of the more powerful new tools in. NET 3.5.
by November 15. 2007 @ 4:56 pm This is not related to this affix. But it would be great if you can (if you have no already) affix about using dates. What to store in DB if the go out is keep how to sight out and what to display if go out is not entered while creating a row - what to pass etc. Basically your thoughts and techniques you would use.
by November 16. 2007 @ 7:30 am Nice write up. I think it would be useful if we all started referring to these things as C# 3.0/VB9 features instead of. NET 3 x given that we can use them in. NET 2.0 projects as come up.
by November 16. 2007 @ 9:37 am Some of the features (like this one) is available both in VB. NET as well as C#. Where as some of the features like Automatic Properties only is available in C#. It would be nice to have a table that would show new features and the language it is available in. Something like:Feature C# VB. NET-------------------------------------------------------------Anonymous Types Y YAutomatic Properties Y N
by Bryan Watts November 16. 2007 @ 9:53 am Hi Rick! Excellent affix. Sorry to affix off-topic but: what syntax highlighter do you use? I haven't found a solution that meets my communicate's needs and your code samples always be great.
by November 16. 2007 @ 6:47 pm @Daniel - isn't that what I did here? <g> Well we have Microsoft to thank for the runtime confusion that surrounds the new features versions. I sure wish a more sane convention would have been used. Certainly. NET 3 x should have not been a 3 x but 2.5 or something to that effect.. too late. Hopefully uptake and installations of 3.5 ordain happen quickly so in the future we can drop about this versioning madness. Maybe 4.0 will consolidate everything - yeah alter.@Bryan - I use Live Writer for my posts with the CopySourceAsHtml add-in in Visual Studio. I then use paste as Html in Live Writer. There are also a couple of attach from Visual Studio plugins for live writer but I actually find the combination of the above the best solution because the VS add-in is highly configurable about how text gets pasted. I've been meaning to act that add-in label (it comes with source) and create another LiveWrite close in that does all of that in one pass but I haven't had time...
by November 27. 2007 @ 2:47 am @Rick - LOL. yeah that's what you did until the measure declare (measure evince change surface?) of the post that spoiles it <g>.@yaip - Not a table but a graphic/glide showing the co-occur of each language feature go across C# and VB is on my blog.
Forex Groups - Tips on Trading
Related article:
http://west-wind.com/weblog/posts/189329.aspx
comments | Add comment | Report as Spam
|