Delegate inference allows you to make a direct assignment of a method name to a
delegate variable, without wrapping it first with a delegate object.

The oldwayclass shows implementation in C# 1.1

class OldWayClass
{
   delegate void notifyDelegate();
   public void InvokeMethod()
   {
      notifyDelegate del = new notifyDelegate(SomeMethod);
      del();
   }
   void SomeMethod()
   {...}
}


and the NewWayClass is the sample implementation in C# 2.0

class NewWayClass
{
   delegate void notifyDelegate();
   public void InvokeMethod()
   {
      notifyDelegate del = SomeMethod;
      del();
   }
   void SomeMethod()
   {...}
}

When you assign a method name to a delegate, the compiler first infers the delegate's type. Then the compiler verifies that there is a method by that name and that its signature matches that of the inferred delegate type. Finally, the compiler creates a new object of the inferred delegate type, wrapping the method and assigning it to the delegate. The compiler can only infer the delegate type if that type is a specific delegate type—that is, anything other than the abstract type Delegate. Delegate inference is a very useful feature indeed, resulting in concise, elegant code.