Should the null extension method always be written in .NET?

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);// not null-proof } } 

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); // throws NullReferenceException 

 Foo foo2 = null; foo2.Baz(); // again throws NullReferenceException 

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.

+4
source share
2 answers

It depends on how you look at extension methods. Given that they are just syntactic sugar on top of the regular static method, I would say that they should follow the recommendations for static methods - check all arguments, including the this parameter.

This is especially applicable if you have extensions specifically designed to handle null - I know that this is not the preferred use of extensions for most people, but I enjoy methods like:

 public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source) { return source ?? Enumerable.Empty<T>(); } public static void DisposeIfNotNull(this IDisposable source) { if (source != null) source.Dispose(); } 

Obviously, the parameters must be null for these methods to work.

+8
source

When I have such a problem in my organization, I agree by default.

Anyone who has an opinion about this knows what it is about. It only depends on whether they look at extension methods from the instance or the static side.

I used WWLD (what would LINQ do?) Before, because it is a shared library that uses extension methods that most .NET developers use.

Code example:

 IEnumerable<int> test = null; test.Where(t => t > 0); // throws an ArgumentNullException 

So, regardless of my opinion, I would use an ArgumentNullException , as other .NET developers will use this.

+3
source

Source: https://habr.com/ru/post/1480124/


All Articles