There is a very strong reason to prefer the first line.
Every delegate has a Target property, which allows delegates to refer to instance methods, even after the instance has gone out of scope.
public class A {
public int Data;
public void WriteData() {
Console.WriteLine(this.Data);
}
}
var a1 = new A() {Data=4};
Action action = a1.WriteData;
a1 = null;
We can't call a1.WriteData(); because a1 is null. However, we can invoke the action delegate without a problem, and it will print 4, because action holds a reference to the instance with which the method should be called.
When anonymous methods are passed as a delegate in an instance context, the delegate will still hold a reference to the containing class, even though it's not obvious:
public class Container {
private List<int> data = new List<int>() {1,2,3,4,5};
public void PrintItems() {
//There is an implicit reference to an instance of Container here
Listdata.ForEach(s => Console.WriteLine(s));
}
}
In this specific case, it is reasonable to assume that .ForEach is not storing the delegate internally, which would mean that the instance of Container and all its data is still being retained. But there is no guarentee of that; the method receiving the delegate might hold onto the delegate and the instance indefinitely.
Static methods, on the other hand, have no instance to reference. The following will not have an implicit reference to the instance of Container:
public class Container {
private List<int> data = new List<int>() {1,2,3,4,5};
public void PrintItems() {
//Since Console.WriteLine is a static method, there is no implicit reference
data.ForEach(Console.WriteLine);
}
}