C# Generics, Comparing 2 strings fail unless explicitly specified
I thought i've seen it all but this... :)
I was working on a generic graph of type string,
Graph<string> graph = new Graph<string>();
Graph is declared with a class constraint like this:
public class Graph<T> where T : class
Next i fill up the graph with some dynamicly generated strings:
for (char t = 'A'; t < 'J'; t++)
{
GraphPrim.Add(t.ToString());
}
So far so good, (Node is a internal class containing the origina开发者_开发技巧l value and a list of references to other nodes (because its a graph))
Now, when i try to create relations between the different nodes, i have to look up the right node by checking its value and thats where the weirdness starts.
The following code, is a direct copy of the result found in the immidiate window after doing some tests:
Nodes.First().Value
"A"
Nodes.First().Value == "A"
false
Nodes.First().Value.ToString() == "A"
true
Am i totally missing something or shouldn't Nodes.First().Value == "A" use a string comparison method. (The JIT compiler has knowledge about the type beeing used on runtime, and with that, its supported methods, right?). It seems to me like when not explicitly specifying a string, it will do a reference check rather then a string test.
It would be great if someone could explain this to me,
Thanks in advance!
If the types aren't fully known up front (i.e. Value
is only known as T
, and is not strictly known to be a string), use things like:
object.Equals(Nodes.First().Value,"A")
Of course, you could cast, but in this case you'd need a double-cast ((string)(object)
) which is ugly.
If you know the two objects are the same type (i.e. two T
values), then you can use:
EqualityComparer<T>.Default.Equals(x,y)
The advantage of the above is that it avoids boxing of structs and supports lifted Nullable<T>
operators, and IEquatable<T>
in addition to Equals
.
If the Value
property of your Nodes is object
, the ==
operator in
Nodes.First().Value == "A"
will do a comparison by reference instead of comparing strings.
==
is a static method and therefore not virtual. The selection of which ==
method to use is done at compile-time, not run-time. Depending on the compile-time type of the object, it is probably choosing the implementation of ==
for objects that compares by reference.
If you use the virtual Equals
methods instead, this will work as you expect.
精彩评论