What is the difference in string.Equals("string") and "String".Equals(string)? - c#

Is there any difference in following two lines of code that compares the string values.
string str = "abc";
if(str.Equals("abc"))
and
if("abc".Equals(str))
in the first line I am calling the equals method on string variable to compare it with string literal. The second line is vice versa. Is it just the difference of coding style or there is a difference in the way these two statements are processed by the compiler.

The only difference is that, in the first case, when you do:
str.Equals("abc")
If str is null, you'll get an exception at runtime. By doing:
"abc".Equals(str)
If str is null, you'll get false.

The difference is that in the second example, you will never get a NullReferenceException because a literal can't be null.

To add to the other answers: the static string.Equals("abc", str) method always avoids triggering a null reference exception, regardless of which order you pass the two strings.

As mmyers said, you the second example will not throw a NullReferenceException and while allowing the program to "appear" to run error free, may lead to unintended results.

Yes, the way the compiler processed the statements is different. The function equals for String in most languages follows the same guidlines. Here is a semicode:
override def Equals(that:String):Boolean //Should override Object.Equals
if(that==null) return false
for i from 0 to this.length
if(!this(i).Equals(that(i))) return false
return true
Normally, the method will fisrt check that that IS a String, and that this and that have the same length.
You can see, as others pointed out, that if that is null the method returns false. On the other hand, the method is part of of String so it cannot be called on null. That is why in your exampleif str is null you will get a NullReferenceException.
That being said, if you know both variables are non-null Strings of the same length, both statements will evaluate to the same in the same time.

Related

What is the boolean result of assign null to a variable

I almost sure those two codes are equivalent, but not sure why.
First is the how I usually do it, i think the safe and more readable way.
string userLine = Console.ReadLine();
while (userLine != null) {
// do things with userLine
userLine = Console.ReadLine();
}
Second one works but not sure why. Because Im comparing an assigment to null.
string userLine;
while ((userLine = Console.ReadLine()) != null) {
// do things with userLine
}
I believe you are thinking that the assignment operation doesn't return any value or returns a Boolean value. That is not correct.
See: = Operator
The assignment operator (=) stores the value of its right-hand operand
in the storage location, property, or indexer denoted by its left-hand
operand and returns the value as its result.
So your statement
while ((userLine = Console.ReadLine()) != null) {
is getting the value from Console.ReadLine assigning the result to userLine and returning the same value, which is compared with null.
The reason behind it works well is because, parenthesis () have highest operator precedence. Once assignment is done, compile will compare the the value of that variable to the null.
Having assignment in parenthesis chains your assignment. And that is the reason, it works.
Not only on Assignment, it works with return values too.
return (value = Console.ReadLine());
But yes, the first one is more readable approach.
The second code works because != operator has left associativity.
So that first
(userLine = Console.ReadLine())
execute, after that comparison happen.
And you are right the first approach is more readable.
If you want to get more information about associativity please refer https://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx
In most likely scenario it is a function call and on return of the function the return value is stored either in done data GPR(general purpose register) or at top of stack. So, the next statement will just use that location and compare against null. Now you see fit generated code it doesn't make any difference... If you want to be sure, generate the assembly file during compilation and check for yourself. All compilers provide option to keep generated files...

A little bit of string cast

Update:
When a database returns a value through the scalar, it will always be an object. So when the value is returned you should have a preconceived notion of what the type will be. Why would you use ToString(); when you you have a SELECT which passes two parameters.
As if it doesn't exist it will always throw a null. So in my refactor I believed the as would be the proper approach. As ToString() will throw an error --- So what form of cast is it comparable to?
I've got some code I'm maintaining, but in apart of my refactor I came across a ToString() attached to an ExecuteScalar. My question would be, does the usage of ToString() equate to:
(string)command.ExecuteScalar();
Or would it represent this:
command.ExecuteScalar() as string;
Obviously the as string would fail gracefully, where the cast (string) would actually fall into an InvalidCastException. So when you call:
command.ExecuteScalar().ToString();
Which method of casting is it attempting to do?
No, it doesn't mean either of those - it simply means calling ToString() on whatever the value is.
In particular, if the value is not a string, it will convert it to a string anyway - whereas string would fail with InvalidCastException and the as would return null.
So for example:
object x = 10;
string a = x.ToString(); // "10"
string b = x as string; // null
string c = (string) x; // Bang
Of course, ToString() can still throw an exception too - most obviously if the target of the call is a null reference.
Personally, I would suggest using a cast if you know what the result type should be - although the result of ExecuteScalar is more commonly a numeric value (e.g. a count) rather than a string.
Yes, that means an exception will be thrown if you're wrong - but if your query isn't doing what it's meant to anyway, then stopping due to an exception may well be better than going ahead with a bogus view of the world. (See my blog post on casting vs as for more on this attitude.)
Neither, because Object.ToString() will returns you a string representation of the object. Regardless whether the query returns a varchar or int.
If command.ExecuteScalar() returns null then it would be something like null.ToString() which will break your production code.
also (string)command.ExecuteScalar() can break your code.
I would suggest to use below line
var result = command.ExecuteScalar() as string;
if(result != null)
{
//your code
}
Let's think about it for a bit.
When you do command.ExecuteScalar() you get back and object in a lot of cases based on the provider you get an int.
What happens is the order of operations triggers
Command.ExecuteScalar() gets and object back.
We are assuming he is an int for the excercise we get that int back.
To String gets called which is defined in the int32 object itself.
You get back the string that was determined inside.
For the most part toString is not meant to throw an exception if no one has implemented in the chain you just get the object type back which is the implementation on the object.
With that said in the case of the int it would probably be the one above. Note if execute scalar returns null to string will error out since null is not an object.
Hope that helps.
P.S. If you tell me the object type of ExecuteScalar i can give you a better answer.

Why does integer.equals(string) give false when both contain the same value, but does not throw type mismatch exception?

I have code where I get a string as input, and I compare it with an integer.
I saw that integer variable also has an Equals function that accepts a string parameter.
I have used it directly thinking it will typecast it.
It did not give any compile time or runtime error, but it always gives a false result.
For example,
int sessionId = 1;
string requestId="1"
return sessionId.Equals(requestId);
sessionId.Equals(requestId) always gives false.
Why is the reason for such behavior? If there is a reason, why are they allowing it run without error?
Integers and strings are always different, and thus "1".Equals(1) returns false.
It compiles because object.Equals(object other) takes an object as the right side, and thus accepts any type.
The reason why this happens is that a string "0" is not the same as 0, so it returns false.
Why is such behavior supported? Because the Equals method allows you to pass an object as a parameter, and a string is in an object, so you are "allowed" to do it. As you have found, it's not very useful in this case.
To solve your problem either get a string representation of the integer, or parse your string to an integer, then compare.
E.g. Try
return (sessionId.ToString() == requestId);
or
return (sessionId == int.Parse(requestId));
If you choose the later you may need to consider if the Parse could fail and how you might handle that.
Yes, Equals takes any type on the right side because it is requires an object. But inside the function it requires the same type as the left side. IMHO there's no need to throw an exception for type mismatching because one only wants to know about equality of two types.
Decompiled Equals of int:
public override bool Equals(object obj)
{
return obj is int && this == (int)obj;
}
If someone shows you a car and a banana, and asks whether they are the same thing, would you throw a temper tantrum because a car is a vehicle and a banana is a fruit, or would you simply say "no, they are not the same thing"?
In many languages, trying to compare an integer and a string will yield a compiler error, because the compiler knows that the integer and the string cannot possibly be the same thing and thus any code that tried to compare them would almost certainly be erroneous. On the other hand, when you say sessionId.Equals(requestId), the compiler knows that you are asking that requestId be passed to the Int32 override of Equals. Since that override can accept a reference to any kind of heap object, it has no problem passing the string "1". That method in turn knows that it was given something which isn't the same as an Int32 with the value 1. It doesn't know that the calling code can't possibly supply anything that would match an Int32; all it knows is that the particular value isn't the same, and because the value isn't the same it perfectly happily returns false.
Shouldn’t we be using String.Compare for string comparison and forget about Equals?
I did have the same problem and I believe the function Equals should throw an exception. In my case, I have been comparing a string with a Boolean.
The discussion by now went wrong way. This is my view:
If a comparison between objects belonging to two different classes always returns false, then they do not need to be compared in the first place.
If there is a need to have a function that bypasses type checking, there should be one. However, having the function Equals positioned as a recommended method for string comparison and in the same time introducing the possibility of unneeded bugs (which may sit in your program for eternity) is a kind of irresponsible.
Moreover, it is extremely misleading that the function call String.Equals(string1, string2, StringComparison. xxx) also accepts non-string arguments. Thus not only string1.Equals(string2).
If that is by design, then it is a poor design.

variable.ToString() vs. Convert.ToString(variable)

Let's say I have an integer that I need to convert to a string (I might be displaying the value to the user by means of a TextBox, for example.
Should I prefer .ToString() or Convert.ToString(). They both do the same thing (don't they?).
int someValue = 4;
// You can do this
txtSomeValue.Text = someValue.ToString();
// Or this...
txtSomeValue.Text = Convert.ToString(someValue);
Assuming that there is no runtime difference between the two, then my reasons come down to aesthetics and consistency. Recently I have been favouring Convert.ToString() as to me it says "hey, I want the value of this thing as a string". However I know that this is not strictly true...
One test is
//This will set the variable test to null:
string test = Convert.ToString(ConfigurationSettings.AppSettings["Missing.Value"]);
//This will throw an exception:
string test = ConfigurationSettings.AppSettings["Missing.Value"].ToString();
Got the above ready example from http://weblogs.asp.net/jgalloway/archive/2003/11/06/36308.aspx
You can find some benchmarks between the two at
http://blogs.msdn.com/brada/archive/2005/03/10/392332.aspx
So, it depends what you prefer and what your style is.
With its large number of overloads, Convert.ToString() is useful as a catch-all for all sorts of input types, handy when you are dealing with a potential range of types. If you know that your input is definitely an "int", I would use the ToString() method on it directly (that's what Convert.ToString() is going to be calling by proxy anyways.)

DataRow comparison not working as expected

I'm trying to compare two DataRows in a loop. However, the following if statement doesn't return true:
if (dt1.Rows[0]["Name"] == dt2.Rows[b]["Name"]) {
// This never executes
}
However, if I add .ToString() to the end of each DataRow, the if statement returns true:
if (dt1.Rows[0]["Name"].ToString() == dt2.Rows[b]["Name"].ToString()) {
// This now executes
}
The column "Name" is from the same table/column. So the question is quite simple... What am I doing wrong?
Thanks
Stephen
Those cells hold objects so you are doing an object comparison, which just does a reference comparison, which is different from a value comparison. It asks the question "Are these two objects really the same object?", essentially are they referring to the same object, hence "reference comparison". When you do the ToString() call, you are then doing string comparison. That is why it works.
Here's a link to MS's discussion of Operator== and comparison.
As itsmatt has said, your first snippet is doing a reference comparison. An alternative to calling ToString is to use Object.Equals:
if (Object.Equals(dt1.Rows[0]["Name"], dt2.Rows[b]["Name"])) {
// stuff
}
The reason for using the static method instead of the instance method is to avoid problems with null references.
The == operator, if not overloaded, is identical to ReferenceEquals() -- that is, it determines whether two given objects are the same instances.
The call to ToString() returns an object of string class, which has overloaded == operator, which does string comparison.

Categories

Resources