C# / Programming

C# anonymous class

While C# has both classes and structures (that are not the same as the one in C++) They also have an interesting creature, the anonymous class.

What is that?

The anonymous class is there to serve a fast requirement to group few properties together. In JavaScript this will be an object. In Python, dictionary, and so on. To declare an anonymous class, we need to use var, and need not to use the class keyword:

var person=new{Name="john"}
Code language: C# (cs)

This code will create a person object, with a Name property, that has the value of “john”. This value will be read only, and technically, you can’t include any private members or methods. However, lambdas are technically variables, so it is possible to create a lambda property like so:

delegate double Calc(int x,int y); Calc triangle=(x,y)=>(Math.Sqrt(x*x+y*y)); var c1=new{Name="temp", Runner=triangle}; Assert.Equal( Math.Sqrt(13),c1.Runner(2,3));
Code language: C# (cs)

So now we have an anonymous class, that can actually execute a function call. Now a function call is not a method, you can’t use members in a function. But can you actually create method on what seems to be a data class?
Well, it seems that you can!

delegate string Announce(dynamic source); Announce calling=(o)=> o.Name; var c2=new{Name="Robert",Runner=calling}; Assert.Equal("Robert", c2.Runner(c2));
Code language: C# (cs)

Using dynamic, we basically tell the compiler – “don’t worry, we got it”. Now, if that’s me, I worry. I don’t like dynamic object unless there is a very good reason of using them, but if needed (and you want to make sure they are needed!), there is a way!

What kind of other magic can dynamic do?

You can actually return an anonymous object using dynamic. Again, this is not the best practice, but it is doable:

dynamic getDBObject() { return new {Name="Bob",Friend="Alice"}; } public void TestName() { var val=getDBObject(); Assert.Equal("Bob", val.Name); }
Code language: C# (cs)

The var keyword is just to help you, and you can just use dynamic instead:

dynamic getDBObject() { return new {Name="Bob",Friend="Alice"}; } public void TestName() { dynamic val=getDBObject(); Assert.Equal("Bob", val.Name); }
Code language: C# (cs)

Now note that there is no telling what val is actually going to be. That might be OK (or actually, the only way) for languages like python, JavaScript and alike(and even then you can check for the type) but definitely not the right thing to do when you are dealing with a static language. Nevertheless – you might encounter a situation where you need to call a dynamic object. BTW – even on these types you can still check for a type, although if you know the type, why would you check it? If you know there is a subset of methods you need to call, you can (and you should!) use an interface. This will give you some compile time checking as to what you are passing.

What if you only need to pass a simple object?

This is a very valid point. I don’t want to create a class for every data that I’m passing back. So anonymous classes seems great, right? Well, no. There is a better way: You can just use tuples:

(string,string) getDBObject2() { return ("Bob", "Alice"); }
Code language: C# (cs)

Now, while we are returning typed object, there is no member calling. Can we use member calling? Yes we can!

(string Name, string Friend) getDBObject2() { return ("Bob", "Alice"); }
Code language: C# (cs)

And this code is fully testable:

(string Name, string Friend) getDBObject2() { return ("Bob", "Alice"); } public void TestName3() { var obj2=getDBObject2(); Assert.Equal("Alice",obj2.Friend); }
Code language: C# (cs)

Note that here everything is being checked at compile time. Far safer. And there is no need for a class declaration. Two birds in one stone.

Leave a Reply

Your email address will not be published. Required fields are marked *