Suppose we have defined an extension method that takes this form:
public class Foo { public void Bar(int arg) { ... } } public static class FooExtensions { public static void Baz(this Foo @this) { @this.Bar(0);
Here we disclose the publicly available Baz extension method in the Foo class (the example is trivial). Now, if we have the following uses:
Foo foo1 = null; foo1.Bar(0);
Foo foo2 = null; foo2.Baz();
Thus, the code in both cases will behave sequentially - regardless of the call to the member method or extension method, we will get the same NullReferenceException () that was selected. It makes me feel that something is wrong in this situation. My thoughts:
- Code that allows
NullReferenceExceptions bad, according to most recommendations. The extension method is an example of such bad practice. In order to abide by the rules and set fault-tolerant code, since there must be a public API, some security checks must be done, for example:
public static void Baz (this Foo @this)
{
if (@this == null)
{
throw new ArgumentNullException ("@ this");
}
@ this.Bar (0);
}
- Consistency in behavior will allow the developer to easily detect a zero reference situation, since both cases behave the same. I mean, calling the extension method is not always obvious to the encoder, so if the string
foo2.Baz() NullReferenceException , it is obvious that foo2 is null .
The above contradiction leads to some conclusions. The second point does not take into account an important problem - stack traces. In the standard case of a NullPointerException stack trace leads directly to the string foo1.Bar(0) . In the extension method, it will point to the line inside the extension method where the exception is thrown. Thus, persistent behavior still has an inconsistent stack trace.
And now the question is about zero security, how do "best practices" apply to extension methods that will be used by third parties? Should consistency be ignored by adding the null-proof validation argument to the @this parameter always? Or is it a corner case that can help us get around good practice tips?
Edit
I am referring to a situation where a library with extensions will be opened. It will not use non-embedded / third-party solutions such as PostSharp or other similar methods. Full compatibility with .NET 3.5 is also required.
source share