Does the order of checking whether a string is null or empty matter?
Does the order of checking whether a string is null or empty matter?
For my programming exam I had to defend code I had written. One of the lines are:
if(app.Logourl == "" || app.Logourl == null)
He asked me whether there was a difference between null and an empty string. I told him that the difference was that null
means its not pointing to anything, so it's not instantiated, but the empty string is.
After the exam I walked up to him and asked him if I was correct, since I saw a funny look on his face. He told me that it's true they're different, but the order in which I checked the values was incorrect.
Now a few days later I believe there's nothing wrong with the order. Am I correct?
TL;DR
is
if(app.Logourl == "" || app.Logourl == null)
equivalent to
if(app.Logourl == null || app.Logourl == "")
Answer by Paul Draper for Does the order of checking whether a string is null or empty matter?
No, it doesn't matter (in your case).
One thing to know though, is that boolean operators &&
and ||
short-circuit, which means if you have a || b
and a
is true
, then b
is not evaluated.
For example,
app.Logourl == null || app.Logourl == ""
If app.Logourl
is null
, then app.Logourl == ""
is never even evaluated.
In your case, there's no real difference whether you check one or the other. first or the other first. If there checks were different, it could matter.
For example,
app.Logourl == null || app.Logourl.Equals("")
If you did the other order, you would get an exception if app.Logourl
is null
, since you can't call member functions of null references.
Though I'd use String.IsNullOrEmpty(app.Logourl)
, which is the standard lib.
Answer by dasblinkenlight for Does the order of checking whether a string is null or empty matter?
It's OK the way you did it, because the overload of ==
for System.String
calls String.Equals
, which allows null
s.
This is not universal, however: if you wanted to check string length instead of using == ""
, your first code snippet would be in trouble:
if(app.Logourl.Length == 0 || app.Logourl == null) // <<== Wrong!
while the second one would be fine:
if(app.Logourl == null || app.Logourl.Length == 0) // <<== Correct
The reason for this is short circuiting in the evaluation of ||
and &&
operators: once they know the result (true
for ||
, false
for &&
) they stop evaluation. In the second snippet above, if app.Logourl
is null
, the second half of the expression will be ignored, hence app.Logourl.Length
would not throw a null reference exception.
Note: In recognition of checks like this happening all over the place, C# class library offers a convenience method for doing this check:
if (string.IsNullOrEmpty(app.Logourl)) { ... }
Answer by Sag1v for Does the order of checking whether a string is null or empty matter?
when I'm sure that my object is a string
I always prefer the following:
if (string.IsNullOrEmpty(yourString)) { // this string is null or empty }
or this:
if (string.IsNullOrWhiteSpace(yourString)) { // this string is null or empty (or got only a space) }
Answer by Jeppe Stig Nielsen for Does the order of checking whether a string is null or empty matter?
This is just a comment.
In usual situations it won't matter. But there can be side effects. Here is a simple example to learn from:
static class Program { static string Logourl { get { Console.WriteLine("getter runs"); return null; } } static void Main() { if (Logourl == "" || Logourl == null) { } } }
This program will write:
getter runs getter runs
If you swap the order of the checks, getter runs
will only print once. If you change the property to return "";
, it will be opposite.
Using string.IsNullOrEmpry(Logurl)
will always retrieve the property exactly once, of course.
Answer by Roman Ambinder for Does the order of checking whether a string is null or empty matter?
private static bool IsNullOrEmpty(string s) { return s == null || s == ""; /* Lets look behind the scenes here: ================================= IL_0000: ldarg.0 => load s on the evaluation stack IL_0001: brfalse.s IL_000f => GoTo label 'IL_000f' if loaded argument is null IL_0003: ldarg.0 => load s on the evaluation stack IL_0004: ldstr "" => load constant string "" to the evaluation stack IL_0009: call bool [mscorlib]System.String::op_Equality(string, string) => Call String.Equality(string,string) with s and "" loaded to the evalutation stack that will pop the two values compare them for equality and load the result. to the evaluation stack. IL_000e: ret => Return to the caller with equlity result on the evauation stack. IL_000f: ldc.i4.1 => Load constant value 1(4 byte which will represent "True") to the evaluation stack and return to the caller.In our flow it's the case when s is null. IL_0010: ret In Summary: =========== 1.) IL instructions total code size 17 bytes. 2.) Best case scenario execution path => 2 IL instructions. 3.) Worst case scenario execution pat => 8 IL instructions. */ } private static bool IsEmptyOrNull(string s) { return s == "" || s == null; /* Lets look behind the scenes here: ================================= IL_0000: ldarg.0 => load s on the evaluation stack IL_0001: ldstr "" => load constant string "" to the evaluation stack IL_0006: call bool [mscorlib]System.String::op_Equality(string, string) IL_000b: brtrue.s IL_0012 IL_000d: ldarg.0 => load s on the evaluation stack IL_000e: ldnull => load constant null on the evaluation stack IL_000f: ceq => Pop two loaded values compare and push the result back on the evaluation stack IL_0011: ret IL_0012: ldc.i4.1 => Load constant value 1(4 byte which will represent "True") to the evaluation stack and return to the caller.In our flow it's the case when s is null. IL_0013: ret In Summary: =========== 1.) IL instructions total code size 20 bytes. 2.) Best case scenario execution path => 6 IL instructions. 3.) Worst case scenario execution path => 10 IL instructions. */ }
Conclusion:
Judging only by the IL emitted code "if(app.Logourl == "" || app.Logourl == null)" is "microptimization" better performance wise :)
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment