So far, we have learned that objects come from a class. A class is declared with a number of fields, properties and/or methods, and then you can create an instance of this class as an object. However, with the introduction of anonymous types, you no longer have to declare a class before creating an object. Don't worry, classes are not dead at all, because anonymous types (or objects) comes with several limitations, but for some situations, they're really great!
An anonymous type is initialized using the new operator, in combination with an object initializer - in that regard, it's very much like instantiating a class, only you leave out the class name. Also, since there's no class behind the object, you must use the var keyword when retrieving the reference to your object. This might sound complicated, but the following example should demonstrate to you that it's not complicated at all:
var user = new
Name = "John Doe",
Age = 42
Console.WriteLine(user.Name + " - " + user.Age + " years old");
That's it - we now have an object with information (name and age) about a user. Anonymous types are great for a lot of situations, especially when you just need to return something quickly, with more complexity than just a string or a number. Anonymous types allow you to make up properties on the fly, without worrying about declaring a class first and then alter this class when your need changes. But as mentioned, there are several limitations that you need to be aware of when you consider using an anonymous type over defining a class:
- Unlike a real class, an anonymous type can't have fields or methods - only properties
- Once the object has been initialized, you can't add new properties to it
- Properties are readonly - as soon as the object has been initialized, you can't change their values
But with that said, anonymous types are still extremely practical for a lot of tasks. A common usage scenario is when you have a complex object (from a defined class) and you need to simplify it, e.g. because you have to keep the object as small as possible to send it to a browser or perhaps because the full object has sensitive information that you don't want to expose to the consumer. Anonymous types are great for this, as illustrated in this next example:
static void Main(string args)
string pathOfExe = System.Reflection.Assembly.GetEntryAssembly().Location;
FileInfo fileInfo = new FileInfo(pathOfExe);
var simpleFileInfo = new
Filename = fileInfo.Name,
FileSize = fileInfo.Length
Console.WriteLine("File name: " + simpleFileInfo.Filename + ". Size: " + simpleFileInfo.FileSize + " bytes");
The first line will simply get us the filename of the currently executing file, that is, our own application. We use it to create an instance of the FileInfo class, which will then contain a LOT of information about this specific file. We don't want all that information, so we create a simplified version of it with an anonymous type, using the information from the original FileInfo instance. In the last line, we use this information for some basic output.
You have probably noticed that we give a name to each of the properties defined in our anonymous type (Filename and FileSize) - that makes pretty good sense, since we want to access them later on. However, when basing our object on information from an existing object, we can actually leave out our own name and let the compiler just use the name of the property we assign to it, like this:
var simpleFileInfo = new
Now, we have two properties called Name and Length, instead of Filename and FileSize. A pretty nice convenience, if you don't care about the names or perhaps more likely: If you actually prefer the exact same names as the original object.
Anonymous types allow you to quickly instantiate an object with one or several properties. These properties are readonly, and you can't add more properties at a later point.