Why can't I use String.Contains () if the default string is null?

From the MSDN doc :

public bool Contains( string value ) 

Return value: true if the value parameter occurs inside this string, or if the value is an empty string (""); otherwise false .

Exception: ArgumentNullException : null .

Example:

 string s = string.Empty; //or string s = ""; Console.WriteLine(s.Contains("Hello World!")); //output: False 

If I changed it to:

 try { string s = null; //or string s; Console.WriteLine(s.Contains("Hello World!")); } catch (Exception e) { Console.WriteLine(e.Message); } 

It gives an error message: Object reference not set to an instance of an object , since string does not have a default value (for example, "" ) from the Default table (C # link) ,

Return to the example, the code will work if I declare s :

 string s = ""; 

Now object s set to an instance of the object.

So my question is: did MSDN forget something like: s cannot be null ?

To test this, I tried:

 string s = null; Console.WriteLine(!string.IsNullOrEmpty(s) ? s.Contains("Hello World!") : false); 

It should work.

+7
string c #
source share
3 answers

You have changed the value to an instance .

 myString.Contains(anotherString) 

Here, myString is the instance you call the Contains method on, while anotherString is the value passed to the method. If this value is null , the method will raise an ArgumentNullException .

When changing the instance to null , on the other hand, this will certainly lead to NRE, since you cannot call any of the null reference. However, if you set it to string.empty Contains , it will return false because the empty string does not contain anything (in particular string.empty does not contain "Hello World" , however "Hello World" contains the empty string).

So false returned:

 Console.WriteLine(string.Empty.Contains("Hello World")); 

So far, this returns true :

 Console.WriteLine("Hello World".Contains(string.Empty)); 

In any case, what do you want to check if the empty IS string is contained in any other:

 var retVal = myString.Contains(string.empty); 

Which should return true .

In addition, myString.Contains(null) ArgumentNullException

On the other hand, null.Contains(aString) results in an NRE.

+9
source share

the new compiler allows you to do this with a simplified state check.

 string s = null; Console.WriteLine(s?.Contains("Hello World!")); 
+2
source share

This question seems to be more related to the difference between value types (which cannot be null) and reference types (which can be). In C # and other OO languages, this is about memory handling.

The value types listed in your MSDN article have all known sizes - for example, int will always be 32 bits, etc. Under the hood, they are all structs . Since they have a fixed size regardless of the value, C # stores them on the stack. Since null by definition does not refer to anything, it has no size. This does not make sense for what exists with a fixed size, which also exists without any size.

If you read the documentation for string in MSDN a little closer, you will see that string is a class, not a structure. This is because the string can be of any length that you like, so you need to save it as a pointer to some data on the heap . When you declare a variable of a reference type, it creates a pointer on the stack to a place on the heap, but there will be nothing at that address until you give this variable a value. Until then, a pointer to this variable indicates and the memory contains literally nothing - i.e. null , and it makes no sense to try to find "Hello World!" not with anything. An empty string is still a string, but null literally nothing.

This is probably more detailed than you expected, but it’s good to have an assessment of the fundamental principles of the language, even if you do not need them day after day. This article is worth reading if you want to delve into it. The idea of null may be a strange concept to plunge into your head, but as soon as you hang it, everything makes sense, honestly!

0
source share

All Articles