Welcome to MSDN Blogs Sign in | Join | Help

Immutable is, the new Anonymous Type

Overview

In the spirit of keeping my first post short and simple, i plan to write about changes to Anonymous tyes that will be of interest to quite a few developers. Anonymous types are immutable, yes its true. Now depending on your current project, prevaling point of view or things you would have read this might seem to be a good or bad thing for you. I will try and throw some light on why this is done and what the change is. Before we begin, In a quick seach on live i found many posts on Anonymous types and If you want to know, what Anonymous types are ? or how to use them ? I would recommend WesDyer's blog.

Since anonymous type's equality and hashcode sematics are defined by its structure ( name, type and order of members) making them immutable has interesting benefits of making the hashcode perform like a well behaved .Net type. That is the hashcode of the object does not change over its lifetime. And since the equality operator can be written to use hashcode, it benefits too, while still maintaining equality based on the structure of the Anonymous Type.

In order to understand this better let's have a look at the GetHashCode Function, which compute the hash by doing the below computation for every member 

hash += hash * change + (field == null ? 0 : EqualityComparer<T>.Default.GetHashCode(fieldMember))

Therefore by ensuring that the members do not change, we ensure that the hash is constant for the lifetime of the object.This allows anonymous types to be used with collections like hashtables, without actually loosing them when the members are modified. There are a lot of benefits of immutabilty in that, it drastically simplifies the code that uses the object since they can only be assigned values when created and then just used (think threading). It also scopes out the feature for the primary purpose that it is designed, the definition of composite keys in Queries where equality based on structure and selecting projections from the results of a Query.

eg of join between 2 composite keys that have a common structure

from p in products  // A composite key equality

join  sl in shoppingList on new {p.Name, p.Category} equals new {sl.ItemName, sl.Cat}

select p;

or creating projections from the results sequence. 

from p in products

where p.UnitPrice >= 100

select new { Name = p.Name, Price = p.UnitPrice }; //or creating projections from the results sequence.

The Bottom line: So what's the result of these changes on the structure of Anonymous types

  1. The Constructor will takes arguments to initialize the fields backing the public properties on the anonymous type 
  2. The default Constructor will be removed.
  3. The public properties will only have getters and no setters
  4. The name of the parameters for the constructor will be the same as the public propertes.
  5. Anonymous type construction will no longer be realized as an Object initalizer (since the anonymous type is created in a single call), but as a single constructor call.
  6. The fields are readonly.

Anonymous types construction can generate IL to be executed or an Expression Tree which can then be translated.

IL Changes

Each Anonymous Type now has a constructor that accepts the values assigned to each member on the type as arguments. The Parameter (name & type) will match the Property (name & type) on the type. As an example, consider
var v = new { A = 5, b = "bar" };

will result in constructor like public AnonymousType(TypeParameter1 A, TypeParameter2 b);  // notice the param A matches property A
and properties like 
    public TypeParameter1 A { get; }  //property A is readonly
    public TypeParameter2 b { get; }

and used as 
var v = new AnonymousType<int, string>(5, "bar");

Further 2 instantiations of a anonymous-type using the same name & types in the same order, will automatically map to the same generic type. Though this is nothing new and has little to do with immutability I thought I mention it for completeness.

var v = new { A = 5, b = "bar" }; var v1 = new { A = 10, b = "Sree" };

will result in 
    var v = new AnonymousType<int, string>(5, "bar");
    var v1 = new AnonymousType<int, string>(10, "Sree");

Expression Tree

There are 2 new overloads for the "New" method added to Expression tree API that support representing anonymous types. They are ...

public static NewExpression New(ConstructorInfo constructor, IEnumerable<Expression> arguments, IEnumerable<MemberInfo> members)

public static NewExpression New(ConstructorInfo constructor, IEnumerable<Expression> arguments, params MemberInfo[] members)

they create and return the NewExpression object which is used to represent this Anonymous type construction as data (the changes to NewExpression class are shown below). The NewExpression class now has a members collection, this corresponds to the list of members that the arguments should be asigned to, below are some of the changes to the NewExpression class.

public sealed class NewExpression : Expression {

        ReadOnlyCollection<MemberInfo> members;

     public ReadOnlyCollection<MemberInfo> Members{

            get { return this.members; }

        }

}

The C# compiler also uses these overloads when it rewrites an anonymus type as an expression tree, this typically happens when creating queries for IQueryable like

string s = "Hello Anonymous types";

var query = from c in s.AsQueryable()

           select new { ASCII = (int)c };

The Compiler passes in the property getters in the member’s collection, Dlinq uses this expression tree to do its translation and every one is happy. 

So when will this be avaiable ?

These changes to the compiler and the System.Core should be publically avaiable in Beta 2.

I would love to hear if you found this information usefull and things i could do to present this material better. (too much code, too little code.. more pictures etc). 

 

Published Tuesday, April 03, 2007 5:41 PM by Sree_c
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Immutable is, the new Anonymous Type

Saturday, April 14, 2007 3:27 AM by zproxy

Nah, the post is just great :)

By the way in LINQ May the initializer syntax was unable to initiate a generic type like this:

new Foo<int> {

bar = 0

};

But i guess this is or will be fixed, right?

# re: Immutable is, the new Anonymous Type

Sunday, April 15, 2007 8:47 PM by Jules

The decision seems smart to me.

Could you expand more on why you've only now decided to make this decision instead of earlier?

Could you also explain any performance implications of this decision?

# re: Immutable is, the new Anonymous Type

Tuesday, April 17, 2007 5:34 PM by Sree_c

Yes, intializer syntax with generic types will work... though there is no type inference so

var v = new Foo<int> { bar = 0 }; // will work

var v1 = new Foo { bar = 1 }; // won't work

Sree

# re: Immutable is, the new Anonymous Type

Tuesday, April 17, 2007 8:35 PM by Sree_c

I think the simple reason we did not do this early is probably because we did not foresee all the issues, and there are always requests from customer to do interesting with anonymous types :).

The Performace implication is are that

1. Its a single call (ctor) instead of ctor and initializers.

2. Possible limitation on the number of arguments that a constructor can take ... none discovered.

# Community Convergence XXV

Saturday, April 21, 2007 1:09 PM by Charlie Calvert's Community Blog

Visual Studio Orcas Beta 1 is available for download . Though quite similar to the March CTP in terms

# re: Immutable is, the new Anonymous Type

Tuesday, April 24, 2007 4:46 AM by Herman

Hello,

I was wondering wether the immutable new

anonymous type has a constructor with the same anonymous type as an argument.

Like:

var v = new { A = 5, b = "bar" };

var v1 = new {v}

Which should translate to:

var v = new AnonymousType<int, string>(5,"bar");

var v1 = new AnonymousType<int,string>(v);

So that the anonymousType class has a constructor with the same  anonymousType  as an argument.

# re: Immutable is, the new Anonymous Type

Tuesday, April 24, 2007 4:56 AM by Herman

To clearyfy my last remark:

The AnonymousType<int,string> defined

by specifying/inferring the types and names of its parameters.

Does this type also has a constructor with

a single argument of type AnonymousType<int,string>

like so

class AnonymousType<int,string>{

 private int _a;

 private string _s;

 public AnonymousType(int a,string s){

    _a=a;

    _s=s;

 }

 public AnonymousType(   AnonymousType<int,string> source){

    _a=source._a;

    _s=source._s;

 }

 ... other members ...

}

}

# re: Immutable is, the new Anonymous Type

Tuesday, April 24, 2007 5:57 PM by Sree_c

There are no current plans to have copy constructor for the Anonymous Types.

Could you explain the reasoning behind this.

Since the Instance are immutable having a copy does not buy much.

Creating another instance of the anonymous types which is a copy involves knowing the names/values/order of the arguments, these should be avaiable if the new instance is created in the same method as the first.

var v = new { A = 5, b = "bar" };

var v1 = new { A = 5, b = "bar" };

v.Equals(v1);

Anonymous types escape functions only as type "System.Object".

# Anonymous method remain mutable in VB.

Friday, May 11, 2007 7:52 PM by @ Head

Paul Vick posted that anonymous types will remain mutable in VB . Generally this looks good, I just hope

# re: Immutable is, the new Anonymous Type

Saturday, May 12, 2007 4:03 PM by Fabrice Marguerie

After reading Paul Vick's post, I'm not sure whether anonymous types will be mutable or not.

Could clear this up, please?

http://www.panopticoncentral.net/archive/2007/05/11/20566.aspx

# VB.NET to the rescue

Monday, May 14, 2007 4:58 PM by Claudio Brotto

Ho sempre sostenuto che VB.NET fosse un linguaggio creato più per ragioni di mercato che per reali necessità

# re: Immutable is, the new Anonymous Type

Wednesday, September 12, 2007 10:38 AM by george moudry

Immutable anonymous types are now implemented in DB_Linq - a LINQ provider for MySql, Oracle and Postgres

# Debugging C# 3.0 Part II

Thursday, November 29, 2007 4:57 PM by Sree's ventures in code space

Overview In the last article I covered the &quot;results view&quot; for lazy evaluated collections like

# 我眼中的C# 3.0

Thursday, June 05, 2008 7:41 PM by 冰封的心

你是如何创建属性的?

如果你长期使用C#,相信你不会对属性这个东西感到陌生。一般地,属性是对私有字段的一个简单包装,就像这样: 代码1

使用属性而不是直接公开私有字段的一个好处就是...

# 我眼中的C# 3.0

Friday, June 06, 2008 11:25 PM by lemontree

转自:http://allenlooplee.cnblogs.com/

缘起

每次有新技术发布时,我们总能感受到两种截然不同的情绪:一种是恐惧和抵抗,伴随着这种情绪的还有诸如

# 我眼中的C# 3.0

Tuesday, July 01, 2008 10:31 PM by 眼里无神

缘起

每次有新技术发布时,我们总能感受到两种截然不同的情绪:

一种是恐惧和抵抗,伴随着这种情绪的还有诸如

# 我眼中的C# 3.0

Tuesday, September 23, 2008 4:39 AM by joinger

每次有新技术发布时,我们总能感受到两种截然不同的情绪:

一种是恐惧和抵抗,伴随着这种情绪的还有诸如

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker