views:

396

answers:

2

Take this class as example:

public class Category : PersistentObject<int>
{
    public virtual string Title { get; set; }
    public virtual string Alias { get; set; }

    public virtual Category ParentCategory { get; set; }
    public virtual ISet<Category> ChildCategories { get; set; }


    public /*virtual*/ void Add(Category child)
    {
        if (child != null)
        {
            child.ParentCategory = this;
            ChildCategories.Add(child);
        }
    }
}

When running the application without the virtual keyword of add method, I getting this error:

method Add should be 'public/protected virtual' or 'protected internal virtual'

I understand why properties need to declare as virtual, because thay need to be overridden by the lazy loading feature.

But I don't understand why Methods need to be declare as virtual... they need to be overridden for what reason?

This very confusing!

A: 

I believe this is required for the lazy-loading feature in NHibernate where NHibernate creates proxies of your entity and controls all access to it. This is why every single method and property must be virtual. Basically, if there is a member doing anything with the entity, NH need to know about it and tap into it. Like mentioned earlier, in order for NHibernate to do the 'magic' it creates proxy classes which inherit from your entities (Category in your case). However, if you make your entities implement an interface, it will use that interface to create a proxy instead of concrete types. This way, you wouldn't have to mark everything virtual.

EDIT: Some corrections... According to this, i am compelled to say that it almost looks like NH doesn't really do anything with virtual methods, after all. And i even read someone saying that they removed this run-time check from the NH core assembly just to get around it. My assumption would be that it is an older requirements which hasn't been removed. The cool thing is that it looks like there is an initiative to use PostSharp for static proxies, so your classes won't have to declare anything virtual for NH to generate proxies. The bad thing is that it looks like it's been stuck in a branch for almost two years.

Sergey
The asker was asking about the rational for requiring methods specifically to be virtual. He explained that he already understands the proxy classes for lazy-loading.
gWiz
A: 

Methods as well need to be virtual because they could access fields. Consider this situation:

class Entity
{

  //...
  private int a;
  public virtual int A 
  { 
     get { return a; }
  }

  public virtual void Foo()
  {
    // lazy loading is implemented here by the proxy
    // to make the value of a available
    if (a > 7) 
    // ...
  }
}
Stefan Steinegger