I am designing a helper method that does lazy loading of certain objects for me, calling it looks like this:
public override EDC2_ORM.Customer Customer { get { return LazyLoader.Get<EDC2_ORM.Customer>( CustomerId, _customerDao, ()=>base.Customer, (x)=>Customer = x); } set { base.Customer = value; } }
when I compile this code I get the following warning:
Warning 5 Access to member ‘EDC2_ORM.Billing.Contract.Site’ through a ‘base’ keyword from an anonymous method, lambda expression, query expression, or iterator results in unverifiable code. Consider moving the access into a helper method on the containing type.
What exactly is the complaint here and why is what I’m doing bad?
‘base.Foo’ for a virtual method will make a non-virtual call on the parent definition of the method ‘Foo’. Starting with CLR 2.0, the CLR decided that a non-virtual call on a virtual method can be a potential security hole and restricted the scenarios in which in can be used. They limited it to making non-virtual calls to virtual methods within the same class hierarchy.
Lambda expressions put a kink in the process. Lambda expressions often generate a closure under the hood which is a completely separate class. So the code ‘base.Foo’ will eventually become an expression in an entirely new class. This creates a verification exception with the CLR. Hence C# issues a warning.
Side Note: The equivalent code will work in VB. In VB for non-virtual calls to a virtual method, a method stub will be generated in the original class. The non-virtual call will be performed in this method. The ‘base.Foo’ will be redirected into ‘StubBaseFoo’ (generated name is different).