In order to answer the question about why the virtual ICollection enables lazy loading in EF, we need the definition and meaning of the virtual keyword in C#. From MSDN:
The virtual keyword is used to modify a method, property, indexer or event declaration,
and allow it to be overridden in a derived class. For example, this method can be
overridden by any class that inherits it.
It is a part of the inheritance mechanism from the Object Oriented Programming concept.
It is often the case, that a sub-class needs another (extended) functionality as the base class. In such case the virtual keyword allows the programmer to override ( the default implementation of the base class for this current implementation if desired, but all other predefined methods/properties/etc. are still taken from the base class!
A simple example would be:
// base digit class
public class Digit
{
public int N { get; set; }
// default output
public virtual string Print()
{
return string.Format("I am base digit: {0}", this.N);
}
}
public class One : Digit
{
public One()
{
this.N = 1;
}
// i want my own output
public override string Print()
{
return string.Format("{0}", this.N);
}
}
public class Two : Digit
{
public Two()
{
this.N = 2;
}
// i will use the default output!
}
When two objects are created and Print is called:
var one = new One();
var two = new Two();
System.Console.WriteLine(one.Print());
System.Console.WriteLine(two.Print());
The output is:
1
I am base digit: 2
The lazy evaluation in EF comes not from the virtual keyword direct, but from the override possibility that the keyword enables (again from MSDN on Lazy Loading):
When using POCO entity types, lazy loading is achieved by creating
instances of derived proxy types and then overriding virtual
properties to add the loading hook.
When the predefined methods are overriden, then the programmer could enable lazy loading!