Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Insight into LINQ and its different components in .NET C# 3.5

Your Ad Here

LINQ Components


Because LINQ is so powerful, you should expect to see a lot of systems and products become LINQ
compatible. Virtually any data store would make a good candidate for supporting LINQ queries. This
includes databases, Microsoft’s Active Directory, the registry, the file system, an Excel file, and so on.
Following are the components for usage.


LINQ to Objects
LINQ to Objects is the name given to the IEnumerable<T> API for the Standard Query Operators. It is
LINQ to Objects that allows you to perform queries against arrays and in-memory data collections.
Standard Query Operators are the static methods of the static System.Linq.Enumerable class that you
use to create LINQ to Objects queries.


LINQ to XML
LINQ to XML is the name given to the LINQ API dedicated to working with XML. This interface was
previously known as XLinq in older prereleases of LINQ. Not only has Microsoft added the necessary
XML libraries to work with LINQ, it has addressed other deficiencies in the standard XML DOM, thereby
making it easier than ever to work with XML. Gone are the days of having to create an XmlDocument
just to work with a small piece of XML. To take advantage of LINQ to XML, you must have a reference to
the System.Xml.Linq.dll assembly in your project and have a using directive such as the following:
using System.Xml.Linq;


LINQ to DataSet
LINQ to DataSet is the name given to the LINQ API for DataSets. Many developers have a lot of existing
code relying on DataSets. Those who do will not be left behind, nor will they need to rewrite their
code to take advantage of the power of LINQ.


LINQ to SQL
LINQ to SQL is the name given to the IQueryable<T> API that allows LINQ queries to work with
Microsoft’s SQL Server database. This interface was previously known as DLinq in older prereleases
of LINQ. To take advantage of LINQ to SQL, you must have a reference to the System.Data.Linq.dll
assembly in your project and have a using directive such as the following:
using System.Data.Linq;


LINQ to Entities
LINQ to Entities is an alternative LINQ API that is used to interface with a database. It decouples the
entity object model from the physical database by injecting a logical mapping between the two. With

this decoupling comes increased power and flexibility, as well as complexity. Because LINQ to Entities
appears to be outside the core LINQ framework, it is not covered in this book. However, if you find
that you need more flexibility than LINQ to SQL permits, it would be worth considering as an alternative.
Specifically, if you need looser coupling between your entity object model and database,
entity objects comprised of data coming from multiple tables, or more flexibility in modeling your
entity objects, LINQ to Entities may be your answer.

 

Happy Reading for more in-depth knowledge of LINQ  in future blogs.

Subscribe
Posted in Labels: kick it on DotNetKicks.com | 28 comments

How to query a SQL Server Database using LINQ

Your Ad Here

This example queries standard Microsoft Northwind sample database

 

using System;
using System.Linq;
using System.Data.Linq;
using northwindEntity;
Northwind db = new Northwind(@"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind");
var custs =from c in db.Customers
                 where c.City == "Rio de Janeiro"
                 select c;
foreach (var cust in custs)
Console.WriteLine("{0}", cust.CompanyName);

You may need to change the connection string that is passed to the Northwind constructor in above code for the connection to be properly made.

In the above given example, we are using System.linq and System.Data.Linq name spaces and our own NorthwindEntity namespace which contains the classes for northwind database.you u can see that I added a using directive for the northwindEntity namespace. For this example to work,you must use the entity framework class, or the Object Relational Designer, to generate entity classes for the targeted database, which in this example is the Microsoft Northwind sample database. . The generated entity classes are created in the northwindEntity namespace, which I specify when generating them. I then add the entity generated source module to my project and add the using directive for the northwindEntity namespace.  Rest of example is self explanatory.

 

Happy Coding.

Subscribe
Posted in Labels: kick it on DotNetKicks.com | 0 comments

LINQ Tutorail Part4

Your Ad Here

This is the forth of a series of articles exploring new features in C# 3. The first three have covered:
  • Implicitly typed variables and arrays
  • Extension methods and lambda expressions
  • Object and collection initializers and anonymous types
To understand this part you should have read the previous three parts of the series, since we will be drawing on features described in all of them.

Introducing Linq

Linq is short for Language Integrated Query. If you are used to using SQL to query databases, you are going to have something of a head start with Linq, since they have many ideas in common. Before we dig into Linq itself, let's step back and look at what makes SQL different from C#.

Imagine we have a list of orders. For this example, we will imagine they are stored in memory, but they could be in a file on disk too. We want to get a list of the costs of all orders that were placed by the customer identified by the number 84. If we set about implementing this in C# before version 3 and a range of other popular languages, we would probably write something like (assuming C# syntax for familiarity):
List Found = new List();
foreach (Order o in Orders)
if (o.CustomerID == 84)
Found.Add(o.Cost);
Here we are describing how to achieve the result we want by breaking the task into a series of instructions. This approach, which is very familiar to us, is called imperative programming. It relies on us to pick a good algorithm and not make any mistakes in the implementation of it; for more complex tasks, the algorithm is more complex and our chances of implementing it correctly decrease.

If we had the orders stored in a table in a database and we used SQL to query it, we would write something like:
SELECT Cost FROM Orders WHERE CustomerID = 84
Here we have not specified an algorithm, or how to get the data. We have just declared what we want and left the computer to work out how to do it. This is known as declarative or logic programming.

Linq brings declarative programming features into imperative languages. It is not language specific, and has been implemented in the Orcas version of VB.Net amongst other languages. In this series we are focusing on C# 3.0, but the principles will carry over to other languages.

Understanding A Simple Linq Query

Let's jump straight into a code example. First, we'll create an Order class, then make a few instances of it in a List as our test data. With that done, we'll use Linq to get the costs of all orders for customer 84.
class Order
{
private int _OrderID;
private int _CustomerID;
private double _Cost;
public int OrderID
{
get { return _OrderID; }
set { _OrderID = value; }
}
public int CustomerID
{
get { return _CustomerID; }
set { _CustomerID = value; }
}
public double Cost
{
get { return _Cost; }
set { _Cost = value; }
}
}
class Program
{
static void Main(string[] args)
{
// Set up some test orders.
var Orders = new List {
new Order {
OrderID = 1,
CustomerID = 84,
Cost = 159.12
},
new Order {
OrderID = 2,
CustomerID = 7,
Cost = 18.50
},
new Order {
OrderID = 3,
CustomerID = 84,
Cost = 2.89
}
};
// Linq query.
var Found = from o in Orders
where o.CustomerID == 84
select o.Cost;

// Display results.
foreach (var Result in Found)
Console.WriteLine("Cost: " + Result.ToString());
}
}
The output of running this program is:
Cost: 159.12
Cost: 2.89
Let's walk through the Main method. First, we use collection and object initializers to create a list of Order objects that we can run our query over. Next comes the query - the new bit. We declare the variable Found and request that its type be inferred for us by using the "var" keyword.

We then run across a new C# 3.0 keyword: "from".
from o in Orders
This is the keyword that always starts a query. You can read it a little bit like a "foreach": it takes a collection of some kind after the "in" keyword and makes what is to the left of the "in" keyword refer to a single element of the collection. Unlike "foreach", we do not have to write a type.

Following this is another new keyword: "where".
where o.CustomerID == 84
This introduces a filter, allowing us to pick only some of the objects from the Orders collection. The "from" made the identifier "o" refer to a single item from the collection, and we write the condition in terms of this. If you type this query into the IDE yourself, you will notice that it has worked out that "o" is an Order and intellisense works as expected.

The final new keyword is "select".
select o.Cost
This comes at the end of the query and is a little like a "return" statement: it states what we want to appear in the collection holding the results of the query. As well as primitive types (such as int), you can instantiate any object you like here. In this case, we will end up with Found being a List, though.

You may be thinking at this point, "hey, this looks like SQL but kind of backwards and twisted about a bit". That is a pretty good summary. I suspect many who have written a lot of SQL will find the "select comes last" a little grating at first; the other important thing to remember is that all of the conditions are to be expressed in C# syntax, not SQL syntax. That means "==" for equality testing, rather than "=" in SQL. Thankfully, in most cases that mistake will lead to a compile time error anyway.

A Few More Simple Queries

We may wish our query to return not only the Cost, but also the OrderID for each result that it finds. To do this we take advantage of anonymous types.
var Found = from o in Orders
where o.CustomerID == 84
select new { OrderID = o.OrderID, Cost = o.Cost };
Here we have defined an anonymous type that holds an OrderID and a Cost. This is where we start to see the power and flexibility that they offer; without them we would need to write custom classes for every possible set of results we wanted. Remembering the projection syntax, we can shorten this to:
var Found = from o in Orders
where o.CustomerID == 84
select new { o.OrderID, o.Cost };
And obtain the same result. Note that you can perform whatever computation you wish inside the anonymous type initializer. For example, we may wish to return the Cost of the order with an additional sales tax of 10% added on to it.
var Found = from o in Orders
where o.CustomerID == 84
select new {
o.OrderID,
o.Cost,
CostWithTax = o.Cost * 1.1
};
Conditions can be more complex too, and are built up in the usual C# way, just as you would do in an "if" statement. Here we apply an extra condition that we only want to see orders valued over a hundred pounds.
var Found = from o in Orders
where o.CustomerID == 84 && o.Cost > 100
select new {
o.OrderID,
o.Cost,
CostWithTax = o.Cost * 1.1
};


Ordering

It is possible to sort the results based upon a field or the result of a computation involving one or more fields. This is achieved by using the new "orderby" keyword.
var Found = from o in Orders
where o.CustomerID == 84
orderby o.Cost ascending
select new { o.OrderID, o.Cost };
After the "orderby" keyword, we write the expression that the objects will be sorted on. In this case, it is a single field. Notice this is different from SQL, where there are two words: "ORDER BY". I have added the keyword "ascending" at the end, though this is actually the default. The result is that we now get the orders in order of increasing cost, cheapest to most expensive. To get most expensive first, we would have used the "descending" keyword.

While I said earlier that the ordering condition is based on fields in the objects involved in the query, it actually doesn't have to be. Here's a way to get the results in a random order.
Random R = new Random();
var Found = from o in Orders
where o.CustomerID == 84
orderby R.Next()
select new { OrderID = o.OrderID, Cost = o.Cost };


Joins

So far we have just had one type of objects to run our query over. However, real life is usually more complex than this. For this example, let's introduce another class named Customer.
class Customer
{
private int _CustomerID;
private string _Name;
private string _Email;
public int CustomerID
{
get { return _CustomerID; }
set { _CustomerID = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Email
{
get { return _Email; }
set { _Email = value; }
}
}
In the Main method, we will also instantiate a handful of Customer objects and place them in a list.
var Customers = new List {
new Customer {
CustomerID = 7,
Name = "Emma",
Email = "emz0r@worreva.com"
},
new Customer {
CustomerID = 84,
Name = "Pedro",
Email = "pedro@cerveza.es"
},
new Customer {
CustomerID = 102,
Name = "Vladimir",
Email = "vladimir@pivo.ru"
}
};
We would like to produce a list featuring all orders, stating the ID and cost of the order along with the name of the customer. To do this we need to involve both the List of orders and the List of customers in our query. This is achieved using the "join" keyword. Let's replace our query and output code with the following.
// Query.
var Found = from o in Orders
join c in Customers on o.CustomerID equals c.CustomerID
select new { c.Name, o.OrderID, o.Cost };
// Display results.
foreach (var Result in Found)
Console.WriteLine(Result.Name + " spent " +
Result.Cost.ToString() + " in order " +
Result.OrderID.ToString());
The output of running this program is:
Pedro spent 159.12 in order 1
Emma spent 18.5 in order 2
Pedro spent 2.89 in order 3
We use the "join" keyword to indicate that we want to refer to another collection in our query. We then once again use the "in" keyword to declare an identifier that will refer to a single item in the collection; in this case it has been named "c". Finally, we need to specify how the two collections are related. This is achieved using the "on ... equals ..." syntax, where we name a field from each of the collections. In this case, we have stated that the CustomerID of an Order maps to the CustomerID of a Customer.

When the query is evaluated, an object in the Customers collection is located to match each object in the Orders collection. Note that if there were many customers with the same ID, there may be more than one matching Customer object per Order object. In this case, we get extra results. For example, change Vladimir to also have an OrderID of 84. The output of the program would then be:
Pedro spent 159.12 in order 1
Vladimir spent 159.12 in order 1
Emma spent 18.5 in order 2
Pedro spent 2.89 in order 3
Vladimir spent 2.89 in order 3
Notice that Vladimir never featured in the results before, since he had not ordered anything.

Getting All Permutations With Multiple "from"s

It is possible to write a query that gets every combination of the objects from two collections. This is achieved by using the "from" keyword multiple times.
var Found = from o in Orders
from c in Customers
select new { c.Name, o.OrderID, o.Cost };
Earlier I suggested that you could think of "from" as being a little bit like a "foreach". You can also think of multiple uses of "from" a bit like nested "foreach" loops; we are going to get every possible combination of the objects from the two collections. Therefore, the output will be:
Emma spent 159.12 in order 1
Pedro spent 159.12 in order 1
Vladimir spent 159.12 in order 1
Emma spent 18.5 in order 2
Pedro spent 18.5 in order 2
Vladimir spent 18.5 in order 2
Emma spent 2.89 in order 3
Pedro spent 2.89 in order 3
Vladimir spent 2.89 in order 3
Which is not especially useful. You may have spotted that you could have used "where" in conjunction with the two "from"s to get the same result as the join:
var Found = from o in Orders
from c in Customers
where o.CustomerID == c.CustomerID
select new { c.Name, o.OrderID, o.Cost };
However, don't do this, since it computes all of the possible combinations before the "where" clause, which goes on to throw most of them away. This is a waste of memory and computation. A join, on the other hand, never produces them in the first place.

Grouping

Another operations that you may wish to perform is categorizing objects that have the same value in a given field. For example, we might want to categorize orders by CustomerID. The result we expect back is a list of groups, where each group has a key (in this case, the CustomerID) and a list of matching objects. Here's the code to do the query and output the results.
// Group orders by customer.
var OrdersByCustomer = from o in Orders
group o by o.CustomerID;
// Iterate over the groups.
foreach (var Cust in OrdersByCustomer)
{
// About the customer...
Console.WriteLine("Customer with ID " + Cust.Key.ToString() +
" ordered " + Cust.Count().ToString() + " items.");
// And what they ordered.
foreach (var Item in Cust)
Console.WriteLine(" ID: " + Item.OrderID.ToString() +
" Cost: " + Item.Cost.ToString());
}
The output that it produces is as follows:
Customer with ID 84 ordered 2 items.
ID: 1 Cost: 159.12
ID: 3 Cost: 2.89
Customer with ID 7 ordered 1 items.
ID: 2 Cost: 18.5
This query looks somewhat different to the others that we have seen so far in that it does not end with a "select". The first line is the same as we're used to. The second introduces the new "group" and "by" keywords. After the "by" we name the field that we are going to group the objects by. Before the "by" we put what we would like to see in the resulting per-group collections. In this case, we write "o" so as to get the entire object. If we had only been interested in the Cost field, however, we could have written:
// Group orders by customer.
var OrdersByCustomer = from o in Orders
group o.Cost by o.CustomerID;
// Iterate over the groups.
foreach (var Cust in OrdersByCustomer)
{
// About the customer...
Console.WriteLine("Customer with ID " + Cust.Key.ToString() +
" ordered " + Cust.Count().ToString() + " items.");
// And the costs of what they ordered.
foreach (var Cost in Cust)
Console.WriteLine(" Cost: " + Cost.ToString());
}
Which produces the output:
Customer with ID 84 ordered 2 items.
Cost: 159.12
Cost: 2.89
Customer with ID 7 ordered 1 items.
Cost: 18.5
You are not restricted to just a single field or the object itself; you could, for example, instantiate an anonymous type there instead.

Query Continuations

At this point you might be wondering if you can follow a "group ... by ..." with a "select". The answer is yes, but not directly. Both "group ... by ..." and "select" are special in so far as they produce a result. You must terminate a Linq query with one or the other. If you try to do something like:
var CheapOrders = from o in Orders
where o.Cost <>Then it will lead to a compilation error. Since both "select" and "group ... by ..." terminate a query, you need a way of taking the results and using them as the input to another query. This is called a query continuation, and the keyword for this is "into".

In the following example we take the result of grouping orders by customer and then use a select to return an anonymous type containing the CustomerID and the number of orders that the customer has placed.
var OrderCounts = from o in Orders
group o by o.CustomerID into g
select new {
CustomerID = g.Key,
TotalOrders = g.Count()
};
Notice the identifier "g", which we introduce after the keyword "into". This identifier represents an item in the collection containing the results of the previous query. We use in the select statement. Remember that each element of the collection we are querying in this second query is actually a collection itself, since this is what "group ... by ..." produces. Therefore, we can call Count() on it to get the number of elements, which is the number of orders per customer. We grouped by the CustomerID field, so that is our Key.

Query continuations can be used to chain together as many selection and grouping queries as you need in whatever order you need.

Under The Hood

Now we have looked at the practicalities of using Linq, I am going to spend a little time taking a look at how it works. Don't worry if you don't understand everything in this section, it's here for those who like to dig a little deeper.

Throughout the series I have talked about how all of the language features introduced in C# 3.0 somehow help to make Linq possible. While anonymous types have shown up pretty explicitly and you can see from the lack of type annotations we have been writing that there is some type inference going on, where are the extension methods and lambda expressions?

There's a principle in language design and implementation called "syntactic sugar". We use this to describe cases where certain syntax isn't directly compiled, but is first transformed into some other more primitive syntax and then passed to the compiler. This is exactly what happens with Linq: your queries are transformed into a sequence of method calls and lambda expressions.

The C# 3.0 specification goes into great detail about these transformations. In practice, you probably don't need to know about this, but let's look at one example to help us understand what is going on. Our simple query from earlier:
var Found = from o in Orders
where o.CustomerID == 84
select o.Cost;
After transformation by the compiler, becomes:
var Found = Orders.Where(o => o.CustomerID == 84)
.Select(o => o.Cost);
And this is what actually gets compiled. Here the use of lambda expressions becomes clear. The lambda passed to the Where method is called on each element of Orders to determine whether it should be in the result or not. This produces another intermediate collection, which we then call the Select method on. This calls the lambda it is passed on each object and builds up a final collection of the results, which is then assigned to Found. Beautiful, huh?

Finally, a note on extension methods. Both Where and Select, along with a range of other methods, have been implemented as extension methods. The type they use for "this" is IEnumerable, meaning that any collection that implements that interface can be used with Linq. Without extension methods, it would not have been possible to achieve this level of code re-use.

DLinq and XLinq

In this article I have demonstrated Linq working with objects instantiated from classes that we implemented ourselves and stored in built-in collection classes that implement IEnumerable. However, the query syntax compiles down to calls on extension methods. This means that it is possible to write alternative implementations of Linq that follow the same syntax but perform different operations.

Two examples of this, which will ship with C# 3.0, are DLinq and XLinq. DLinq enables the same language integrated query syntax to do queries on databases by translating the Linq into SQL. XLinq enables queries on XML documents.

Conclusion

Linq brings declarative programming to the C# language and will refine and unify the way that we work with objects, databases, XML and whatever anyone else writes the appropriate extension methods for. It builds upon the language features that we have already seen in the previous parts of the series, but hiding some of them away under syntactic sugar. While the query language has a range of differences to SQL, there are enough similarities to make knowledge of SQL useful to those who know it. However, its utility is far beyond providing yet another way to work with databases.

Closing Thoughts On C# 3.0

This brings us to the end of this four part series on C# 3.0. Here is a quick recap on all that we have seen.
  • Type inference removes much of the tedium of writing out type annotations again and again.
  • Lambda expressions make higher order programming syntactically light.
  • Extension methods provide another path to better code re-use when correctly applied.
  • Object and collection initializers along with anonymous types make building up large data structures much less effort.
  • Linq gives us declarative programming abilities over objects, databases and XML documents.
When I saw C# 1.0 I highly doubted that C# was going to be a language I would ever be excited about. I have been pleasantly surprised, and writing this series has been a lot of fun. I hope that it has been informative and enjoyable to read, and that it will help you to make powerful use of the new language features. I greatly look forward to being able to use them in my own day-to-day development and seeing how other people use them.

Of course, knowing about something and doing it yourself are two entirely different things; if you haven't already done so, grab yourself the Visual Studio 2008 trial or the free Express Edition. Only then will you become comfortable with the new features and be able to use them effectively in your own development. Happy hacking, and have fun!

Subscribe
Posted in Labels: , , kick it on DotNetKicks.com | 0 comments

LINQ Tutorail Part3

Your Ad Here

This is the third of a series of articles exploring new features in C# 3. The first two have covered:
  • Implicitly typed variables and arrays
  • Extension methods and lambda expressions
To follow this part you should certainly have read the first one, but no material from the second part is required.

In this article we will look at object and collection initializers, which provide a neater syntax for setting the initial values of properties for objects and the initial contents of collections. We will then move on to anonymous types, which you need to know about to understand Linq.

Object Initializers

It is fairly common in C# code to see an object be instantiated using the "new" keyword and then having its fields and/or properties set. Until C# 3.0, this could only be done by instantiating the object, storing it in a variable and then doing assignments to the various properties. In C# 3.0, object initializers make this possible within a single expression.

Suppose we want to instantiate a 5 year old male monkey called Norbert and add it to the jungle. In previous versions of C# we would have written:
Monkey NewCreation = new Monkey();
NewCreation.Name = "Norbert";
NewCreation.Sex = SexEnum.Male;
NewCreation.Age = 5;
Jungle.Add(NewCreation);
A few things are frustrating here. First is that if we have to mention the variable, NewCreation, each time. Second, we may not really need the variable NewCreation at all - we just want to add a monkey to the collection. Finally, it would be better from a linguistic point of view if we could have pulled the Add ahead of the monkey creation, so when you read the code you can see the purpose of creating the new monkey.

Object initializers allow us to set the initial values of fields or properties of an object as part of the new statement. For example, we can re-write the above like this:
Monkey NewCreation = new Monkey() {
Name = "Norbert",
Sex = SexEnum.Male,
Age = 5
};
Jungle.Add(NewCreation);
Here we have added a set of curly braces at the end of the "new" expression. Inside them, we can do assignments to the fields and properties without having to write the name of the object that is being referred to. Note the use of commas between the assignments rather than semicolons.

The fact that we don't have to name the object we are initializing - that is, setting the fields/properties of - means we can do a further refactoring:
Jungle.Add(new Monkey() {
Name = "Norbert",
Sex = SexEnum.Male,
Age = 5
});
Now the intermediate variable is gone. Finally, if there are no parameters to pass to the constructor, we are permitted to save ourselves two more characters and remove the brackets after the type name:
Jungle.Add(new Monkey {
Name = "Norbert",
Sex = SexEnum.Male,
Age = 5
});


Initializing Nested Objects

Our Monkey class may have, as one of its fields, an field that holds an instance of the Tail class. In this case, there are two possibilities. One is that the class does not instantiate the Tail for us. In this case, we can use the new keyword to instantiate it and set properties of it - basically, just nesting what we already know.
Jungle.Add(new Monkey {
Name = "Norbert",
Sex = SexEnum.Male,
Age = 5,
Tail = new Tail { Length = 50 }
});
The other possibility is that the class does instantiate tail and we just need to set some properties of it. In this case we can omit not only the "new" keyword, but also the name of the class too, since that can be worked out by the compiler.
Jungle.Add(new Monkey {
Name = "Norbert",
Sex = SexEnum.Male,
Age = 5,
Tail = { Length = 50 }
});
You can nest as deeply as you wish, but be careful not to harm readability. Good use of whitespace can help on that front.

Collection Initializers

Collections can contain many values. Sometimes you will create a collection and then immediately add some values to it. Just as object initializer syntax made a common use case neater for objects, collection initializer syntax makes one neater for collections.

Again, let's take an example. Notice that I am already using the new C# 3 "var" keyword.
var Jungle = new List();
Jungle.Add(new Monkey());
Jungle.Add(new Tiger());
Jungle.Add(new Panda());
Using a collection initializer, we can write this as:
var Jungle = new List
{ new Monkey(), new Tiger(), new Panda() };


You can observe implicit coercion taking place whenever you assign a value of one type to a variable of another without the need to insert a cast.
There are some rules concerning the use of collection initializers. First, if you are writing your own collections and want them to work with collection initializer syntax, they must implement the ICollection interface. Second, the elements of the collection must all be of the same type (or more precisely, they must all have an implicit coercion to a single type).

Initializer Performance

Shorter code doesn't always mean a performance improvement at runtime. In this case, the new object initializer syntax will almost certainly compile down to the same IL instructions as if you had not used it. You might save a tiny amount of memory due to not having to allocate space for the local variable. However, the compiler should have been able to optimize that away anyway. In short, expect equivalent performance: no better and no worse.

Anonymous Types

Anonymous simply means "without a name", and you can safely read the word "type" as "class" in this case. That is, in this section we are going to discuss the idea of classes without names.

In C# 2.0 we saw the introduction of anonymous methods. One of the consequences of a method having no name is that we had to take a reference to it - stored in a delegate type - right away, so we had some way to refer to it. The analogy with anonymous classes is that we are required to instantiate them right away. Therefore, the construct for creating an anonymous class also instantiates that class.

In C# 3.0, anonymous classes are greatly limited compared to standard classes. They can only inherit from object and their only memebers are private fields each with a matching read/write property.

With all of these things in mind, let's see how we declare and instantiate an anonymous type.
var MyProduct = new {
Name = "Vacuum Cleaner",
Price = 94.99,
Description = "Really sucks! Have your carpets clean in no time."
};
There are a couple of things to notice here. First is that we do not have a name for the class. Therefore, there is no type that we can write before the name of the variable when declaring it. What we can do, however, is to write "var", which leaves the compiler to work out the type for us. While the types are anonymous as far as we should care, the compiler and runtime actually do have some way of identifying them.

The second thing to notice is that we have used the "new" keyword but without specifying a type name. Instead, we have placed something after it that looks just like the object initializers we were looking at a few moments ago. This is not a co-incidence: we actually are initializing the object created by new. The question is, where is the definition of the class?

The class is created by looking at the initializer. For each name assigned to inside the initializer (Name, Price and Description in this case), a private field is created along with a get/set property. In this case, the class might look like this:
class __NO_NAME__ {
private string _Name;
private double _Price;
private string _Description;

public string Name {
get { return _Name; }
set { _Name = value; }
}
public double Price {
get { return _Price; }
set { _Price = value; }
}
public string Description {
get { return _Description; }
set { _Description = value; }
}
}
Note that the types of the fields are worked out by looking at what is being assigned to the property. Therefore, you are not allowed to assign a null value. It is the same type inference process that we have seen time and time again in C# 3.0.

Since anonymous classes are just classes and instances of them are just objects, you can do all of the things you'd expect to be able to with them, from simple things like accessing their properties through to more complicated things such as reflection.

Type Equivalence

Type equivalence involves determining if two values are of the same type. In this case, we are concerned with type equivalence of objects instantiated from anonymous classes.

This comes up in practice when assignment is considered. Let's take an example.
var x = new {
Real = 5.4,
Complex = 2.8
};
var y = new {
Real = 1.9,
Complex = 5.3
};
x = y;
Remember from the first part of the series that C# 3.0 is statically typed. That means that the variables x and y both have and retain a given type. Therefore, if the assignment is to work then y has to be of the same type as x (we don't have to consider subtyping here, since anonymous classes always inherit from object).

Two anonymous types will be considered equivalent if all of the following properties are true:
  • They have the same number of fields
  • They have fields of the same name declared in the same order
  • The types of each of the fields are identical
In the previous example, this is the case. However, any of the following changes to the anonymous type that was instantiated to give y will result in the types not being equivalent and the assignment resulting in a compile time error.
// Not equivalent due to an extra field.
var y = new {
Real = 1.9,
Complex = 5.3,
Conjugated = -5.3
};
// Not equivalent - fields in a different order.
var y = new {
Complex = 5.3,
Real = 1.9
};
// Not equivalent; different types (int != double)
var y = new {
Complex = 4,
Real = 2
};


Projections

There is one final feature of anonymous types to point out, and until you see Linq this is going to feel a little obscure. So far we have declared a field in an anonymous type by specifying its name and initializing it to a value. There are two other ways.

The first is to simply write the name of an already declared variable. The name of the variable will be taken as the name of the field, and the value it holds will be used to initialize the field. Using this, you could rewrite:
var x = new {
Real = 5.4,
Complex = 2.8
};
As:
var Real = 5.4;
var Complex = 2.8;
var x = new {
Real,
Complex
};
In this case it complicates the code, but it's worth being aware of. There is a variation on this where instead of naming a variable, you access a member of an existing object. The field takes the name and value of the member.

Imagine we have a class called Customer that represents all of the details of a customer, but we just want an anonymous type that contains the name and email address. We can write the following:
Customer c = GetCustomer(1764);
var EmailRecord = new { c.Name, c.Email };
This is equivalent to:
Customer c = GetCustomer(1764);
var EmailRecord = new {
Name = c.Name,
Email = c.Email
};


Conclusion

Object and collection initializers are partly handy syntactic shortcuts. The real power in them is the ability to instantiate and set up an object with a single expression. This can save us from introducing an extra temporary variable, which can lead to neater code.

Anonymous types probably feel a little strange at the moment. While the other language features we have seen have had immediate obvious practical uses, anonymous types may be a little harder to see the use for.

All will become much clearer in the next and final part of the series, when we look at Linq. Linq is built using all of the primitives we have learnt about so far, so if you have read and understood this and the previous parts of the series, you are ready to understand not just how to use Linq, but how it actually works.

Subscribe
Posted in Labels: , , kick it on DotNetKicks.com | 0 comments

LINQ Tutorail Part2

Your Ad Here

Introducing C# 3 – Part 2

This is the second of a series of articles exploring new features in C# 3. You should read the first one if you have not already done so. In this article we will cover extension methods, a powerful new language feature to increase abstraction and code re-use, and lambda expressions, which take advantage of type inference to deliver a much cleaner syntax for anonymous methods.

Extension Methods

In the beginning – that is, in C# 1.0 – the methods belonging to a class were defined within the body of the class. C# 2.0 changed that somewhat. By introducing partial classes, the methods making up a class could be defined in more than one place. However, they were all collected together at compile time, so it was nothing particularly new. Anonymous methods were something new, however. Conceptually, anonymous methods are associated with no class at all. C# 3.0 continues the journey with extension methods.

Extension methods are associated with a class (either a specific one or they are generic and can work for any class). What makes them different from normal instance methods is that they are not defined within the class itself. Instead, they are defined in some other static class. This all sounds rather strange, so let’s take an example.

Imagine that we had got some third party class library for computing a serial number for a product from a product ID and some user details. The method may take the arguments ProductID, CustomerName, CustomerDateOfBirth, and CustomerCountry. In the class library, its implementation may look something like this:
public sealed class SerialGenerator
{
public long MakeCode(int ProductID, string CustomerName,
DateTime CustomerDOB,
string CustomerCountry)
{
return (ProductID % 42) + CustomerName.GetHashCode() *
(CustomerDOB.Ticks - CustomerCountry.GetHashCode());
}
}
In our application, however, we pass around user data in a structure.
struct UserInfo
{
public int UserID;
public string Name;
public DateTime DOB;
public string CountryCode;
}
What we’d really like is to be able to add a wrapper method to SerialGenerator that takes this structure as a parameter. However, we can’t modify the class since it’s a third party component, and they sealed it so we can’t inherit from it. Sealed classes show up more than you might imagine; the Int and String types, for example, cannot be inherited from.

Extension methods aim to solve these issues. Before we dig into exactly what they are, I’d like to introduce a couple of different ways of thinking about things. First of all, consider the special variable "this", which magically exists in all instance methods. Where does its value come from? Well, look at the syntax for calling a method.
Obj.Method();
A v-table is a table of methods belonging to a class. It contains overridden methods, but in the same position in the table as where the first class to define them placed them. This enables subclassing and polymorphism to work as expected.
Obj is used in two ways. The first is that it refers to the v-table. This can be used to look up the method to call (in the case of method overriding). The second use is that it is passed as the first parameter to the method. This parameter is taken and becomes the "this" variable – this is what the CLR does under the hood. So essentially, all of your instance methods have an implicit first parameter that the C# compiler inserts for you and provides access to through the "this" variable.

Second, there is an alternative way of thinking about object orientation: rather than having a class-based system, you can use multi-methods. Multi-methods are very similar to method overloading in C# - you can have methods with the same name but different signatures, and the right one is invoked depending on the parameters that are used in the call. Now imagine that the implicit first parameter that we just discussed is not implicit, but instead you place it at the start of every method's parameter list. The type of that first parameter can be a class name. When deciding which method to call, the full signature (including the type of the invocant – the first parameter) is taken into account. That means that you can write methods for a particular class anywhere you like in your program, or extend existing classes with your own methods.

Sometimes the object a method is being called on is referred to as the invocant. For example, in obj.method(), obj is the invocant.
If you can get your head around those ideas, then you will find extension methods fairly straightforward. An extension method is a static method, but with the first parameter it takes being explicitly marked as receiving the object that the method was called on. Extension methods may only appear in static classes. Returning to our example, we can implement an extension method like this:
static class Extensions
{
public static long MakeCode(this SerialGenerator SG,
int ProductID, UserInfo User)
{
return SG.MakeCode(ProductID, User.Name, User.DOB,
User.CountryCode);
}
}
Notice the this modifier on the first parameter. This states that it is going to hold the object the method was called on, and therefore can be called using method invocation syntax. To try this out, create a console application with the code shown so far in this article and with the following Main method.
static void Main(string[] args)
{
SerialGenerator SG = new SerialGenerator();

UserInfo User = new UserInfo();
User.UserID = 453;
User.Name = "Fred";
User.DOB = DateTime.Now;
User.CountryCode = "UK";
long Code = SG.MakeCode(5181, User);

Console.WriteLine(Code);
}
Here, the call to MakeCode will call the extension method. We have been able to extend the sealed class.

Another example: Push and Pop for List

I love the generic List collection, but I miss a couple of methods that would be useful now and then. Being able to pretend that the List is a stack and have Push and Pop methods, for example, would lead to clearer code at times.

Now with extension methods we can add Push and Pop support to List.
static class StackOps
{
public static void Push(this List TheList, T Value)
{
TheList.Add(Value);
}
public static T Pop(this List TheList)
{
if (TheList.Count == 0)
throw new Exception("Nothing to pop.");

int LastPos = TheList.Count - 1;
T Result = TheList[LastPos];
TheList.RemoveAt(LastPos);

return Result;
}
}
Note that we have implemented it for a generic List, using the type variable T in the method. We can now use these new methods on any List; in the following example, we used them on a List.
static void Main(string[] args)
{
var Stack = new List();

// Put stuff onto the stack.
for (int i = 0; i <= 10; i++)
Stack.Push(i);

// And now pop stuff off it.
while (Stack.Count > 0)
Console.WriteLine(Stack.Pop());
}
Here I have implemented Push and Pop just for lists, but I could instead have used IEnumerable in place of List when declaring the extension method. This means that every collection that implements this interface can have Push and Pop called on it. This brings up another very powerful feature of extension methods: they allow us to attach implementation to interfaces. We have never been able to do this before.

Thinking about extension methods

Now we've seen what extension methods are, let's spend a little time thinking about the issues they raise. One question that comes to mind is precedence. What if you have an extension method and the class itself implements a method of the same name? The short answer that works for most cases is that the instance method in the class will win. The real answer requires us to consider overloading.

When trying to locate the method to call, first the instance methods are checked. A method is considered a candidate if it has the correct name and a matching parameter list. By matching we mean that it has the same number of parameters as are being passed and the types of the parameters are compatible. If we find a candidate amongst the instance methods, the search ends. If not, the compiler will start looking for extension methods, starting in the innermost namespace and working its way outwards.

This will probably not result in any surprising behavior, but it's worth mentioning the one place it may just catch you. Suppose you have the classes Puppy and Dog, where Puppy is a subclass of Dog. In the Dog class you have an instance method Chase. If you were to write an extension method for the Puppy class called Chase, it would never be called. This is because the inherited method in the class is found as a candidate, so the extension method is never considered, even though in some ways it may be a "better" choice. The following code demonstrates this.
class Dog
{
public void Chase()
{
Console.WriteLine("Chase method of Dog called.");
}
}
class Puppy : Dog
{
}
static class PuppyThings
{
public static void Chase(this Puppy Pup)
{
Console.WriteLine("Chase extension method for Puppy called.");
}
}
class Program
{
static void Main(string[] args)
{
Dog d = new Dog();
Puppy p = new Puppy();
// This calls the method from class Dog, as we expect.
d.Chase();
// So does this, which we might not have expected.
p.Chase();
}
}
Output:
Chase method of Dog called.
Chase method of Dog called.
Another question that comes up is that of performance. Does the runtime have to locate the method to call at runtime, or is it worked out at compile time? The answer is that it is decided at compile time, so there is not any runtime dispatch overhead. In fact, the lookup doesn't even go through the v-table, so it may well be faster than some instance method calls. (For those who like to have the details, the .Net CLR provides an instruction, named "call", for calling a method without consulting the v-table, which the compiler can use instead of the standard one when it knows that it is safe to do so).

Perhaps the most important question, though, is when extension methods should be used. The C# designers themselves say that they are not something you want to be using all of the time, but rather in situations where instance methods are unable to provide what you need.

If you have a class and want to extend it with some special functionality that is specific to your usage of it, you now have two options.
  • Inherit from it and put the special functionality in the sub class
  • Write extension methods
The first option is preferable. Inheritance is well understood by other programmers, it is clear what method will be called and you won't have to repeatedly write the class name when writing the methods. So why the second option? I can think of a few cases.
  • If the class is sealed, you will be unable to inherit from it. In this case, you have no option but to use extension methods.
  • You may be using some kind of object factory that instantiates objects of a given class, but you do not have the ability to modify it so that your subclass is instantiated instead. Therefore extension methods are the only way to extend the functionality of these objects.
  • You want to implement a method that can be invoked on all classes implementing a given interface; before, we had no way to attach a method implementation to an interface.
  • You may want to add related things to a number of other classes, and from a software engineering point of view it may be better to collect those together in one place rather than spreading them amongst many classes.
If you find yourself writing extension methods every day, then that's probably a bad sign. It's a myth that every language feature is intended to be used equally often, both in real and programming languages.

Lambda Expressions

The term "lambda expression" sounds somewhat frightening at first, but there’s no reason to be sheepish. In fact, the lambda calculus – a very simple language where everything is expressed in terms of functions – dates back to the day before we had computers, making it some of the earliest theoretical Computer Science work.

A lambda expression simply defines an anonymous function. A function is something that takes one or more parameters (just as a method does) and uses them in computing some value. That value becomes the return value for the function. In C# 3, the "=>" syntax is used to write a lambda expression. You place the parameters to the left of the arrow and the expression to compute to the right.

For example, here is a function that adds one to the value it is provided with:
x => x + 1
How does this work? Well, it takes one parameter x and then returns the result of doing "x + 1". You can write a Lambda expression that multiplies to numbers quite easily too:
(x, y) => x * y
Here we have taken two parameters, x and y, and the result is the multiplication of them. Note that if we have more than one parameter, we have to place them in parentheses. How about if you do not wish to take any parameters? In this case, you put an empty set of parentheses in place of the parameter.
() => new Beer()
The above function takes nothing and returns beer; this is rarely implemented in the real world. If you want to do something more complex, you can supply a block to the right of the arrow. In this case, you should write a return statement, unless you do not wish to return a value (which is allowable, though not the common case).
(x, y) => {
var result = x + y;
return result;
}


Using Lambda Expressions

At this point you could be forgiven for thinking, "well that's neat, but why?" C# 2.0 added support for anonymous methods. However, the syntax was rather verbose for a feature that, at least amongst some programmers, is used quite often. Let's look at a couple of examples where anonymous methods were used before and see the improvement that we get by using lambda expressions instead.

In this first example, we will take a list of strings, sort them by length and then display the output. We use an anonymous method to give the comparisons.
// Some words.
var Words = new List { "amazingly", "my", "badger", "exploded" };
// Sort them by word length.
Words.Sort(delegate(string a, string b)
{
return a.Length.CompareTo(b.Length);
});
// Show results.
foreach (string Word in Words)
Console.Write(Word + " ");
This prints "my badger exploded amazingly" on the console. We can re-write the sort using a lambda expression.
// Sort them by word length.
Words.Sort((a, b) => a.Length.CompareTo(b.Length));
Which is a lot neater. For a second example, suppose we are rendering some forum markup tags to HTML. We are going to match a tag with a regex, check if the tag is in a list of allowed tags and, if it is, render it to HTML. Otherwise, we'll just leave it unrendered. Here is the original implementation.
// List of tags we accept.
var AcceptedTags = new List { "b", "u", "br" };
// Text to render.
var ToRender = "[b]Bold, [i]bold italic[/i], just bold again.[/b][br]";
// Regex to match tags.
var FindTags = new Regex(@"\[(/?)(\w+)\]");
// Render it.
string Output = FindTags.Replace(ToRender,
delegate (Match m) {
return AcceptedTags.Contains(m.Groups[2].Value) ?
"<" + m.Groups[1].Value + m.Groups[2].Value + ">" :
m.Value;
});
Here we are using an anonymous method to specify code to generate the replacement string. We can replace that with a lambda expression too.
string Output = FindTags.Replace(ToRender,
m => AcceptedTags.Contains(m.Groups[2].Value) ?
"<" + m.Groups[1].Value + m.Groups[2].Value + ">" :
m.Value);


Lambda Expressions And Type Inference

One difference you may have spotted between lambda expressions and the original anonymous method syntax is the absence of types on the parameters. You actually can write the types in if you wish:
(int x, int y) => x + y
Be aware that you need the parentheses for a single parameter if you're going to write a type annotation:
(int x) => x + 1
Even here, there is something more special going on, since nowhere have we declared the type of value that will be returned by the lambda expression. With anonymous methods we had to do that.

In the previous article, I talked about type inference. As a very quick recap, this involves working out the types of variables based on information available in the code rather than making the programmer write them in. This is exactly what is happening here. The interesting question, then, is where is the type information coming from this time?

When a method expects to be passed an anonymous method as a parameter, it uses a delegate type. This delegate type contains the types of the parameters. When a lambda expression is used, it is often being passed as a parameter. Therefore, the delegate type of the parameter will, in turn, enable to compiler to work out what the types of the lambda expression's parameters are.

If you're wide awake, you might be wondering what happens when you have a generic delegate type as a parameter of a method and pass a lambda expression there. And the answer is that yes, you can do this, generic types will be inferred and it should all work out just fine. In fact, some of what LINQ does depends on it working.

Conclusion

In this article we've seen extension methods and lambda expressions. I've taken the time to dive into some of the ugly details, but don't worry if some of them haven't sunk in just yet.

Extension methods offer some powerful new possibilities, but we need to take care in how we use them from a software engineering angle. Don't expect to be using them every day, but remember them for those times when they really are the right thing to use.

Lambda expressions, on the other hand, are for regular use. Even if you aren't doing much higher order programming today, if you plan on using LINQ you soon will be. The biggest hurdle most people have to get over is realizing that it is possible (conceptually, at least) to treat code the same as data. Once you get comfortable with that idea, using anonymous methods or lambda expressions doesn't feel so unusual. Practice and experience help. I'd recommend trying to learn a functional programming language, but if you're reading this you're probably wanting to get C# 3.0 cracked first.

In the next article in the series we'll look at object initializers and anonymous types. These make it easier to build up data structures and set initial values for fields in objects and structures. With that, we will have seen all of the language features that act as the building blocks for LINQ, which will be covered in the final part in the series.

Subscribe
Posted in Labels: , , kick it on DotNetKicks.com | 0 comments

LINQ Tutorail Part1

Your Ad Here

Being a languages guy, watching a language evolve is always of great interest. It was interesting to see features that had tended to be more popular in academic languages making it into C# 2. The prime example of this was generics, a form of parameterised types. Parameterised types had been about in the academic world for quite a while, and so have many of the additions that have made it into C# 3. The advantage of this is that they have been researched well and their semantics are well understood. But before the academic in me takes over, let’s get practical and dig in to how C# 3 will make programming more productive and more fun.

Types

The title of this section say it is about variables, but really it’s about types. If you’ve never ventured outside the C#/Java/C/C++ world, you might assume that a variable declaration always looks something like:
string question = “What is the meaning of life, the universe and everything?”;
int answer = 42;
That is, you always specify the type of the variable (int or string in this case), the name of the variable and then (either on the same line or later on) you initialise it to some value. Since you always specify the type of the variable when you declare it, the types of variables are always known. This means that if you try and assign, say, an integer to a variable of type string, the compiler has enough type information from the declarations to detect this and complain. A variable only ever has one type (though it may hold values that are subtypes of that type) and this type is known at compile time. This is called static typing.

Other people will have looked at languages such as Perl, Python and Ruby and seen that when you declare a variable you don’t have to (or just can’t) specify a type for the variable. Instead, a variable carries a "tag" around with it that specifies the type of the value that it contains. When you assign a value to a variable at runtime, the tag is set with the type of that value. The tag is checked (again, at runtime) before operations are performed on a variable to make sure that they are safe. This is called dynamic typing.

Here is an example of some code that will compile and run in a dynamically typed language, but not in a statically typed one.
a = "something"
if (complex condition that is always true)
a = 84
b = a / 2
Here we have used the variable a as a string, then an integer. In a dynamically typed language that is fine - by the time we do the division, the variable is an integer rather than a string and it all works fine. In a statically typed language, this would fail to compile, since the compiler can not work out at compile time that the condition will always be true at runtime. It is a contrived example, but shows the heart of the issue.

Static typing clearly has the advantage of no runtime checks (though if you write casts into your program some of them will translate to a dynamic type check). That means you get higher performance and don’t get type errors at runtime, unless you’ve explicitly written something into your program that may generate them, in which case you’ve probably thought about what you’re doing.

I’ve dragged you through this whole detour on static vs. dynamic typing because I want you to understand what I mean when I say that C# 3 is statically typed, just as all previous versions have been.

Look! No Types!

Here’s some new C# 3 syntax for declaring the same variables we did earlier.
var question = “What is the meaning of life, the universe and everything?”;
var answer = 42;
At first glance, it appears that you’re declaring a variable of type “var”. Actually, “var” is not a type, but rather a new keyword that means, “I want to declare a variable, but I’m too lazy to write out its type”. For cases where the type is "Dictionary>" or similar, this saves quite a bit of clutter in the code:
// Before:
Dictionary> Coeffs = new Dictionary>();
// After:
var Coeffs = new Dictionary>();
I’ve stated that C# is statically typed, while at the same time showing that you can now declare a variable without specifying its type. What’s going on? The answer is type inference. A type inference algorithm in the compiler analyses your program and works out the type for you; you could see it as, conceptually at least, going through your program and for each occurrence of the keyword "var" figuring out the type of that variable and putting it in place of "var". Therefore, what gets compiled is equivalent to an explicitly annotated program (that is, one where you specify the types of all variables).

If you are thinking of Visual Basic and its Variant types and wondering if there is a similarity here, there isn't. Variants use dynamic typing rather than inferring the type statically. Therefore, variants carried a runtime performance penalty. Using "var" in C# 3 does not. Your program will run just as quickly as if you had written the type in yourself.

Time To Play

Enough theory - it’s about time we wrote some code to explore the idea. To do this, you’re going to need a copy of the C# 3 preview compiler, which is also known as the LINQ preview (where LINQ is the name of one of the most exciting new features in C# 3, and the .Net platform in general). You can download it from through the C# future versions page:

http://msdn2.microsoft.com/en-us/vcsharp/aa336745.aspx

Close Visual Studio if you have it open and install the LINQ technology preview. The next time you enter Visual Studio, you’ll find a new type of project on the New Project menu.

Visual Studio New Project window with LINQ project option.

We’ll just look at console applications in this article. Create a new LINQ Console Application and then open the Program.cs source file. At this point everything should look pretty familiar.

To demonstrate type inference at work, we’ll write a program that declares several variables using var and then print their types. Change the Main method to read as follows.
static void Main(string[] args)
{
var Name = "Jonathan";
var Answer = 42;
var Prog = new Program();
var Friends = new List();
// Print the types of the variables.
Console.WriteLine("Name is of type " + Name.GetType().Name);
Console.WriteLine("Answer is of type " + Answer.GetType().Name);
Console.WriteLine("Prog is of type " + Prog.GetType().Name);
Console.WriteLine("Friends is of type " + Friends.GetType().Name);

// Stop console disappearing.
Console.ReadKey();
}
The output of this program will be:
Name is of type String
Answer is of type Int32
Prog is of type Program
Friends is of type List`1
Notice that basic types are inferred (the first two lines), types of objects are inferred (the third line) and generic types and inferred too (the last line). You can put any expression with a single type to the right of the assignment. For example the following program:
var A = 28;
var B = 14;
var Result = A + B;
Console.WriteLine("Result is " + Result);
Console.WriteLine("Result is of type " + Result.GetType().Name);
Will produce the output:
Result is 42
Result is of type Int32
Here, the types of A and B are inferred as we have seen in the previous example. The type of Result is then inferred by considering the type of value that the plus operator returns when applied to variables of two other types. This means the inferred types of A and B are used, along with knowledge of the behavior of the plus operator, to determine a type for Result.

Subtleties And Corner Cases

There are some subtle issues that you should be aware of when using implicitly typed local variables. First of all, you must initialize the variable when you declare it. This will fail to compile:
// Must be initialized at the point of declaration.
var DoItLater;
Console.WriteLine("We'll do it later...");
DoItLater = "Done it!";
Also, initializing with null is not allowed; this following example will also fail to compile.
// Must not be initialized to null.
var TryItNull = null;
Console.WriteLine("We'll try it null...");
TryItNull = "Tried it!";
A less contrived example where this may hit you is:
// This woulda been nice to be able to do.
var SetConditionally;
if (condition)
SetConditionally = 500;
else
SetConditionally = 600;
Which doesn’t work. The rule is that there must be an expression (other than null) assigned to an implicitly typed local variable for the type to be inferred. Note that if we re-wrote the previous example to:
var SetConditionally = condition ? 500 : 600;
Then it would work, as there is an expression to the right with a type that can be determined. The following example will not work:
var SetConditionally = condition ? 500 : "badger";
Because there is no type that can be inferred (if you think about it, there is no type that you could write in place of var to make this compile anyway). Type inference understands subtyping too. If you write two classes:
class Parent
{
}
class Child : Parent
{
}
Then try the following program:
var Condition = true;
var SetConditionally = Condition ? new Parent() : new Child();
Console.WriteLine("SetConditionally is of type " + SetConditionally.GetType().Name);
This will compile and produce the output:
SetConditionally is of type Parent
Note that if you were to replace var with Parent in this case, the program would compile and run; if you replaced it with Child then it would not. That seems vaguely clever, but unfortunately you don’t have to try hard to find a type that could be safely inferred that, at least in the technology preview, will not be. Consider defining the following interface and two classes that implement it:
interface Animal
{
}
class Dog : Animal
{
}
class Cat : Animal
{
}
We would expect the following program to report that the variable Pet is of type Animal:
var PreferCats = true;
var Pet = PreferCats ? new Cat() : new Dog();
Console.WriteLine("Pet is of type " + Pet.GetType().Name);
Unfortunately, we get a compile time error:
Type of conditional expression cannot be determined because there
is no implicit conversion between 'CSharp3_Examples.Cat' and
'CSharp3_Examples.Dog'
The only way to resolve the problem while using implicit typing is to insert casts:
var PreferCats = true;
var Pet = PreferCats ? (Animal) new Cat() : (Animal) new Dog();
Console.WriteLine("Pet is of type " + Pet.GetType().Name);


Implicitly Typed Arrays

So far we have been looking at implicit typing of variables holding a single value, however implicit typing also extends to arrays. In the case that you initialize the array (that is, specify its elements when you declare it), you need not mention the type of the elements in the array at all; the type will be inferred by considering the type of the elements in the array. For example, the following code:
var Primes = new [] { 2, 3, 5, 7, 11, 13, 17, 19 };
Console.WriteLine("Primes is of type " + Primes.GetType().Name);
Will produce the following output:
Primes is of type Int32[]
Note that if there are any elements whose type cannot be inferred or are the null type, you will get a compile time error. Similarly, if there are elements of different types in the array and the type inferencer cannot find a single type that fits them all, you will get a compile time error. That is, neither of the following examples will compile:
var OneNull = new [] { 1, 4, 9, 16, null, 36 };
var Different = new [] { "String", 123 };


Conclusion

Having the full name of a type, particularly a parameterized one, appearing twice on the same line has been one of my annoyances with C# and Java. The statement:
Dictionary> Example = new Dictionary>();
Can now be shortened to:
var Example = new Dictionary>();
I consider that an improvement, both to developer productivity when writing code and to those reading the code too.

I know some people will consider this to be yet another feature moving C# away from being the simple language they desire. However, since variable declarations are written time and time again, this is hardly adding another feature that will only be used occasionally (an argument that you could apply to, for example, nullable types added in C# 2.0). The fact that it extends to arrays is a good thing.

On the other hand, some people may be disappointed with some of the restrictions with regard to type inferencing, and wish that it could be smarter. It is important to realize that type inference is not even possible for all type systems (more formally, it is not decidable – you can’t write a program that will be able to compute a type in all cases). The designers needed to come up with an implementable and understandable type inferencing scheme that would not restrict them too much with where they want to take future versions of the language.

Anyway, that’s all for this time. Next time we’ll be looking at extender methods (which allow more abstraction and code re-use) and lambda expressions (which will enable us to do higher order programming a lot less verbosely). And finally, if you're wondering if type inference is just about saving you typing a few characters in type annotations, the answer is no: you'll be meeting it again in the remaining parts of this series.

Subscribe
Posted in Labels: , , kick it on DotNetKicks.com | 0 comments