Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Wednesday, October 22, 2008

LINQ ,iterators and Lazy loading

When I first started exploring LINQ queries ,I was excited about lot of its features, particularly the lazy loading of results.

Linq query that retrieves only customer info
var names= for c in db.customer
where c.name.contains("Sree")
select c.name;

Linq query that retrieves customer and some order info
var result = from c in db.customer
where c.orders.orderdate<'01/01/2009'
select c.name, c.orders.orderdate;

So basically if you have a customer entity and orders for that customer, when you access customer, the orders will not be retreived,. it gets filled when you access one of the property of order class. there are ways to change this behavoiur to do full loading.

After knowing that I did some research on what is happenng behind the scenes. so it turned out that LINQ is using the iterator feature and yield keyword to achieve this behaviour.

So when you write a foreach loop as you all know it uses an iterator. Within the iterator you can use the yield keyword to return results one by one or as desired

private static IEnumerable GetOrders()
{
yield return "Order1";
yield retun "Order2";
}

In the above example I have return multiple yield statements, but it could be a loop with one yield statement inside.

nice to know how some things work..

Generic Collections

system.collections.Generic

Interfaces

IEnumerable<T> is the interface that allows to enumerate throught the collection.
ICollection<T> is the generic collection and adds the index capability.
IList<T> implements both IEnumerable<T> and ICollection<T>.

Concrete Implementations
List<T> implements both IList<T> and is basically uses an array behind the scene whose size is dynamically increased as required. Default Initial size being 4. Equivalent non-generic type is ArrayList.

List<T> has lot of capabilities ,but if we want to store a collection of key,value pairs there is another collection available - Dictionary<T> . Equivalent non-generic type is HashTable.

Other collections of interest are- SortedList<T> , LinkedList<T>, Queue<T> ,Stack<T> .

There is no SortedList<T> , but List<T> has sort() method to do the same. But if we want to keep the list sorted always we will need to write some code to do so..

Combining these collections with LINQ provides a lot of cool possibililities for every day scenarios . LINQ requires the object to implement IEnumerable or IQueryable interface.

The best part is that these new generic classes and interfaces are compatible with the old non-generic ones.
public class List :
IList, ICollection, IEnumerable, IList, ICollection, IEnumerable

This means if existing methods uses old interfaces as parmaeter, you still can supply the generic ones.

If you are planning to change all your existing non-generic types in your project to the generic one to improve performance and type safety make sure the generic ones has all the properties and methods available. In most case it may not be a one-to-one mapping.

Monday, October 20, 2008

List<T>

List<T>

List<T> is the new generic class introduced with .net 2.0 that is going to replace most of the Arraylist usage in our code. There are lot of reasons we would want to look at List<T> generic class ..

1. Arraylist collection allows any type (object). so if we put value types like int into arrraylist there is always a performance hit during adding (boxing) and retreival (unboxing ).

performance comparison- ArrayList’s vs. generic List
http://blogs.msdn.com/joshwil/archive/2004/04/13/112598.aspx

2. Strongly typed List<T> class allows type safety during compilation time like any other generic counter part and also reduces coding bugs.

3. Comparing List<T> with LinkedList<T>

LinkedList<T> is the doubly linked list class in .net framework. A List<T> is stored basically as a abig array in managed heap whereas LinkdList<T> can potentially have nodes all over the managed heap. So Inserting a new item into a List could be little more expensive when compared to LinkedList since it will involve shifting items depending on where you are inserting the new item.

List<T> outperform LinkedList<T> in the following area- Adding/removing nodes - ,indexed access/searching (List<T> uses indexer ,whereas LinkedList<T> you must navigate using the previous and next nodes ) .

-sree

IComparable and IComparer

System.Collections.Generic

These two interface were really confusing for me in the begining maybe because of the similarity in the names, but once you understand how it works , they will look simple.

Both of these interfaces provide the same functionality- ability to sort and compare objects.

When you use List<T>.Sort() method , it calls the default comparer
and the overloaded List<T>.Sort(Icomparer) requires you to pass a comparer object.. Let us see more on this...

IComparable<T>

The IComparable interface when implemented provides the means to define a default comparison functionality for a given object. Implement one method - CompareTo() .

public class Customer : IComparable<Customer>{
// The underlying temperature value.
protected m_name = "Sree";

public int CompareTo(Customer other) {
return m_value.CompareTo(other.m_name);
}
}

Because the CompareTo() method is strongly typed , it is not nec to check for the correct data type.

But this Inteface has certain limitations and drawbacks-

This is great if we are happy with only sorting on one attribute (Name) of the Employee class.

if we would like to know how the sort is implemented, we would either have to look at the documentation (if there are, any) or open the Employee class implementation code to understand the sorting logic. This makes IComparable pattern less readable.


IComparer<T>

Enter Icomparer<T> interface , does the same job as Icomparable and defines the sort ranking for any two objects, Except that we dont implement the sorting logic within the same class .

Since you define each comparison logic in seperate classes, you can have multiple ways to sort and compare the objects. And the naming convention of the comparer class (NameComparer, AgeComparer etc ) makes it more readable .

Icomparer<T> exposes the Compare() method.

public class CustomerNameComparer: IComparer<Customer> {
public int Compare(Customer x, Customer y) {
//compare the name fields... }
}

public class CustomerAgeComparer: IComparer<Customer> {
public int Compare(Customer x, Customer y) {
//compare the age fields...
}

//let us use the new object initialier syntax to populate the csuomter list..

List<Customer> customers = new List<Customer>{
new Customer(){ Name="Sree", Age=8 },
new Customer(){ Name="Chris", Age=2},
new Customer() { Name="Helena", Age=14}};

//sort based on name..
customers.Sort( new CustomerNameComparer() );

//and sort based on age...
customers.Sort( new CustomerAgeComparer() );

Final note-
If you dont implement the IComparable interface and CompareTo() method in Customer class and try to call the List<Customer>.Sort() method , you will get an exception.

IEqualityComparer<T> - is a special comparer only used for equality comparison and not sorting and ordering.



-Sree