2

.NET libraries have String.IsNullOrEmpty(value As String).

I can create more comfortable <stringValue>.IsNullOrEmpty() by simple extension method:

<Extension>
Function IsNullOrEmpty(s As String) As Boolean
    Return String.IsNullOrEmpty(s)
End Function

My fist quick understanding was that this was not implemented out-of-the-box because it can throw NullReferenceException in case of null. Until I found this is not true, because Nothing in String variable is typed as string.

Dim s As String = Nothing
If s.IsNullOrEmpty() Then ... 'this will always return true, no exception thrown

Is there point in having default form String.IsNullOrEmpty(s) instead of s.IsNullOrEmpty() which I am missing?

Of course, in Immediate Window I cannot type

? Nothing.IsNullOrEmpty()

but it is nonsense anyway. This works normally:

? CStr(Nothing).IsNullOrEmpty()
miroxlav
  • 11,796
  • 5
  • 58
  • 99

3 Answers3

4

The reason why the default is a static method in String and not a normal method is because calling a method on Nothing/null would cause an exception. So you would have to check for Nothing/null first and then there's no point to call another method to check if it's maybe Nothing/null.

The reason why your extension method doesn't cause this is because it's a method that gets the object as a parameter, just like the static method in String.

But if you mean why the extension method was not done, then Damien_The_Unbeliever's answer is correct: there were no extension methods to begin with. And crating a duplicate would probably be pointless at a later time.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • @miroxlav I don't understand what you mean. I didn't say it gets an `Object` as a parameter, I meant it gets the string object as a parameter as opposed to calling a member method on the string object. – Sami Kuhmonen Aug 15 '15 at 11:04
  • OK, your edit makes sense, but the first paragraph is incorrect because you can call it on null string as I shown in the question. But I understand it is not possible invoke other string methods on null string, so this probably could be a convention. – miroxlav Aug 15 '15 at 11:11
  • @miroxlav You can call the *extension method* on a null string, yes, as I mentioned in the answer. It will cause a call on a static method with the string as an argument, not an actual member function call. But you can't call any actual member functions so that's why it's not a member function. I was unsure if you were asking about extension method or member function. – Sami Kuhmonen Aug 15 '15 at 11:14
3

The reason why it isn't implemented as an extension method (which, at the end of the day, is still just a static method) is historic - Extension methods didn't exist until C# 3 / VB 9 - over half a decade after String.IsNullOrEmpty debuted in .NET 1.0.

Extension methods that don't throw a NullReferenceException when their first parameter is null are actually very confusing to reason about - since that gives them behaviour unlike normal instance methods.

They're confusing enough when the exception is either manually thrown, throw instead as an ArgumentNullException, or just propagate from deep within an implementation (unlike normal instance methods which throw the NullReferenceException at the call site).

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • I see but there is a ton of other methods available for `stringValue` and none of them is an extension method. So do you think they merely didn't want to create a duplicate? – miroxlav Aug 15 '15 at 11:03
  • 1
    @miroxlav - there are a lot of normal methods for strings, and all of them have something in common - you can't call them on a null reference (or `Nothing`, if you prefer). Basically, it would have added a *confusing* duplicate to existing functionality that's unlike the other methods. – Damien_The_Unbeliever Aug 15 '15 at 11:07
1

After all, adding my own answer "For Dummies", maybe it can help someone:

Standard class method cannot be invoked on null, even if that null is of a string (CStr(Nothing)). So simply having stringValue.IsNullOrEmpty() wouldn't work as standard method, in case if stringValue is null.

It would work only with extension method because it is static method actually accepting the object as its first parameter. No problem having null there. But it would be confusing because due to behavior of standard methods, no one might expect invocation of method on null object – it is not common thing and it looks rather like unfixed bug although it isn't. Such a confusion would be imminent especially when reading the source outside the IDE – where extension methods cannot be clearly distinguished from standard ones.

So we can either completely abandon use of extension methods which can be invoked on nulls or give extension methods clear distinction in their names. The latter practice can also help others who are joining the project rising their awareness about any project-related extension methods: "there is something attached to standard class". Such a practice can also prevent confusion on spotting stringValue.IsNull() which is normally a nonsense. There are many ways of writing distinctive name but I think the best would be only to add distinctive character, so names can remain short and unaffected by additional words.

Here's my idea: Outside the US, where we are more used to non-ASCII characters, there are some interesting alphabets like this. One of their distinctive characters can be suitable to add as a glyph to a name, thus creating for example stringValue.IsNullOrEmptyᛎ() which also corresponds to generally used badge graphics for extension methods.

miroxlav
  • 11,796
  • 5
  • 58
  • 99