False Positives From String Comparison using string.Equals()

Discussion in 'ASP .Net' started by Smithers, Jun 20, 2009.

  1. Smithers

    Smithers Guest

    I am using the .Equals() method of the string class, as follows, to compare
    string properties of two different instances of a given class.


    if
    (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    StringComparison.OrdinalIgnoreCase))
    {
    return true;
    }

    What I am observing in testing is that the above .Equals() periodically
    finds that the string values are different when they do not in fact appear
    to be different in any way. By "appear to be different in any way" I mean
    that I hover the mouse over each property and view in the "Text Visualizer",
    then copy from there into Notepad and compare the values in notepad - they
    appear to be the exact same string.

    The bigger picture is this: I'm using Visual Studio Pro 2008. This is
    happening in an ASP.NET Web application. I instantiate the class and
    populate it with values from the underlying SQL Server 2005 database, then
    load those properties into the UI, and then store the object instance in a
    Session variable. Then, when the user navigates to a different page, I
    instantiate a new instance of the class and populate it with values from the
    UI. I then compare relevant properties of that instance - as in the sample
    code above - against the same properties from the instance that was
    previously stored in Session state. I do this to determine if the user
    actually modified any values from the underlying database and therefore
    whether to save any changes to the database.

    How can I compare the strings in a way that would not result in such "false
    positives"? I would think my approach, above, is perfectly fine. What can I
    do differently?

    Thanks.
    Smithers, Jun 20, 2009
    #1
    1. Advertising

  2. Smithers wrote:
    > I am using the .Equals() method of the string class, as follows, to compare
    > string properties of two different instances of a given class.
    >
    >
    > if
    > (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    > StringComparison.OrdinalIgnoreCase))
    > {
    > return true;
    > }
    >
    > What I am observing in testing is that the above .Equals() periodically
    > finds that the string values are different when they do not in fact appear
    > to be different in any way. By "appear to be different in any way" I mean
    > that I hover the mouse over each property and view in the "Text Visualizer",
    > then copy from there into Notepad and compare the values in notepad - they
    > appear to be the exact same string.
    >

    But are they? Your test is not definitive. Whitespace is not distinguishable
    visually and there are plenty of visible characters who share glyphs.

    For starters, compare the string *lengths*. If those are the same, go into
    the immediate window and check if Encoding.UTF8.GetBytes() yields the same
    result on both strings. If that's the case and the strings still don't
    compare equal then you might've found a genuine bug in the framework, but
    that's very unlikely.

    > The bigger picture is this: I'm using Visual Studio Pro 2008. This is
    > happening in an ASP.NET Web application. I instantiate the class and
    > populate it with values from the underlying SQL Server 2005 database


    If you're using CHAR fields (fixed length, whitespace padding,
    encoding-specific) or VARCHAR fields (encoding-specific) as opposed to
    NVARCHAR fields, this could be the cause of your strings not round-tripping.

    --
    J.
    Jeroen Mostert, Jun 20, 2009
    #2
    1. Advertising

  3. This is possible as the DataBase returns spaces.

    However, simply testing (StringX == StringY) gives the same result and in my
    opinion much easier then let it go trough an extra old derived C function.

    Cor


    "Smithers" <> wrote in message
    news:...
    >I am using the .Equals() method of the string class, as follows, to compare
    >string properties of two different instances of a given class.
    >
    >
    > if
    > (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    > StringComparison.OrdinalIgnoreCase))
    > {
    > return true;
    > }
    >
    > What I am observing in testing is that the above .Equals() periodically
    > finds that the string values are different when they do not in fact appear
    > to be different in any way. By "appear to be different in any way" I mean
    > that I hover the mouse over each property and view in the "Text
    > Visualizer", then copy from there into Notepad and compare the values in
    > notepad - they appear to be the exact same string.
    >
    > The bigger picture is this: I'm using Visual Studio Pro 2008. This is
    > happening in an ASP.NET Web application. I instantiate the class and
    > populate it with values from the underlying SQL Server 2005 database, then
    > load those properties into the UI, and then store the object instance in a
    > Session variable. Then, when the user navigates to a different page, I
    > instantiate a new instance of the class and populate it with values from
    > the UI. I then compare relevant properties of that instance - as in the
    > sample code above - against the same properties from the instance that was
    > previously stored in Session state. I do this to determine if the user
    > actually modified any values from the underlying database and therefore
    > whether to save any changes to the database.
    >
    > How can I compare the strings in a way that would not result in such
    > "false positives"? I would think my approach, above, is perfectly fine.
    > What can I do differently?
    >
    > Thanks.
    >
    Cor Ligthert[MVP], Jun 21, 2009
    #3
  4. Cor Ligthert[MVP] wrote:
    > "Smithers" <> wrote in message
    > news:...
    >> I am using the .Equals() method of the string class, as follows, to
    >> compare string properties of two different instances of a given class.
    >>
    >>
    >> if
    >> (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    >> StringComparison.OrdinalIgnoreCase))
    >> {
    >> return true;
    >> }
    >>

    <snip>
    > However, simply testing (StringX == StringY) gives the same result


    That's equivalent to an ordinal comparison, not a case-insensitive ordinal
    comparison like the OP is using.

    --
    J.
    Jeroen Mostert, Jun 21, 2009
    #4
  5. Smithers

    Hans Kesting Guest

    It happens that Cor Ligthert[MVP] formulated :
    > This is possible as the DataBase returns spaces.
    >
    > However, simply testing (StringX == StringY) gives the same result and in my
    > opinion much easier then let it go trough an extra old derived C function.
    >
    > Cor
    >


    No, that would not give the same results.
    "A" == "a" would return false,
    "A".Equals("a", StringComparison.OrdinalIgnoreCase) would return true.

    You are right however to point to the possibility of extra spaces in
    the "database" value. They would not be visible but would mess up the
    comparison.
    As a hint to the OP: that's why I don't just "Console.WriteLine" those
    strings, but add some sort of brackets around them:
    Console.WriteLine("[" + stringToDisplay + "]");
    Then extra spaces would become apparent.

    Hans Kesting

    >
    > "Smithers" <> wrote in message
    > news:...
    >>I am using the .Equals() method of the string class, as follows, to compare
    >> string properties of two different instances of a given class.
    >>
    >>
    >> if
    >> (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    >> StringComparison.OrdinalIgnoreCase))
    >> {
    >> return true;
    >> }
    >>
    >> What I am observing in testing is that the above .Equals() periodically
    >> finds that the string values are different when they do not in fact appear
    >> to be different in any way. By "appear to be different in any way" I mean
    >> that I hover the mouse over each property and view in the "Text
    >> Visualizer", then copy from there into Notepad and compare the values in
    >> notepad - they appear to be the exact same string.
    >>
    >> The bigger picture is this: I'm using Visual Studio Pro 2008. This is
    >> happening in an ASP.NET Web application. I instantiate the class and
    >> populate it with values from the underlying SQL Server 2005 database, then
    >> load those properties into the UI, and then store the object instance in a
    >> Session variable. Then, when the user navigates to a different page, I
    >> instantiate a new instance of the class and populate it with values from
    >> the UI. I then compare relevant properties of that instance - as in the
    >> sample code above - against the same properties from the instance that was
    >> previously stored in Session state. I do this to determine if the user
    >> actually modified any values from the underlying database and therefore
    >> whether to save any changes to the database.
    >>
    >> How can I compare the strings in a way that would not result in such "false
    >> positives"? I would think my approach, above, is perfectly fine. What can I
    >> do differently?
    >>
    >> Thanks.
    >>
    Hans Kesting, Jun 22, 2009
    #5
  6. Smithers

    Merk Guest

    << SNIP>>


    > As a hint to the OP: that's why I don't just "Console.WriteLine" those
    > strings, but add some sort of brackets around them:
    > Console.WriteLine("[" + stringToDisplay + "]");
    > Then extra spaces would become apparent.



    Upon reading from the DB and UI, each string is trimmed (theString.Trim()).
    So, I think that would resolve any extra spaces issue.

    I have yet to try the suggestion by Mr. Covington. That looks like it might
    shed some light on the situation.

    -S
    Merk, Jun 22, 2009
    #6
  7. Hans,

    Most people here are clever enough that they know that it is possible to
    write, I take mostly the shortest notation when I want to show something.

    ("A".ToUpper() == "a".ToUpper())

    Cor

    "Hans Kesting" <> wrote in message
    news:...
    > It happens that Cor Ligthert[MVP] formulated :
    >> This is possible as the DataBase returns spaces.
    >>
    >> However, simply testing (StringX == StringY) gives the same result and in
    >> my opinion much easier then let it go trough an extra old derived C
    >> function.
    >>
    >> Cor
    >>

    >
    > No, that would not give the same results.
    > "A" == "a" would return false,
    > "A".Equals("a", StringComparison.OrdinalIgnoreCase) would return true.
    >
    > You are right however to point to the possibility of extra spaces in the
    > "database" value. They would not be visible but would mess up the
    > comparison.
    > As a hint to the OP: that's why I don't just "Console.WriteLine" those
    > strings, but add some sort of brackets around them:
    > Console.WriteLine("[" + stringToDisplay + "]");
    > Then extra spaces would become apparent.
    >
    > Hans Kesting
    >
    >>
    >> "Smithers" <> wrote in message
    >> news:...
    >>>I am using the .Equals() method of the string class, as follows, to
    >>>compare string properties of two different instances of a given class.
    >>>
    >>>
    >>> if
    >>> (!valuesFromUI.Other_Description.Equals(valuesAsRetrievedFromDB.Other_Description,
    >>> StringComparison.OrdinalIgnoreCase))
    >>> {
    >>> return true;
    >>> }
    >>>
    >>> What I am observing in testing is that the above .Equals() periodically
    >>> finds that the string values are different when they do not in fact
    >>> appear to be different in any way. By "appear to be different in any
    >>> way" I mean that I hover the mouse over each property and view in the
    >>> "Text Visualizer", then copy from there into Notepad and compare the
    >>> values in notepad - they appear to be the exact same string.
    >>>
    >>> The bigger picture is this: I'm using Visual Studio Pro 2008. This is
    >>> happening in an ASP.NET Web application. I instantiate the class and
    >>> populate it with values from the underlying SQL Server 2005 database,
    >>> then load those properties into the UI, and then store the object
    >>> instance in a Session variable. Then, when the user navigates to a
    >>> different page, I instantiate a new instance of the class and populate
    >>> it with values from the UI. I then compare relevant properties of that
    >>> instance - as in the sample code above - against the same properties
    >>> from the instance that was previously stored in Session state. I do this
    >>> to determine if the user actually modified any values from the
    >>> underlying database and therefore whether to save any changes to the
    >>> database.
    >>>
    >>> How can I compare the strings in a way that would not result in such
    >>> "false positives"? I would think my approach, above, is perfectly fine.
    >>> What can I do differently?
    >>>
    >>> Thanks.
    >>>

    >
    >
    Cor Ligthert[MVP], Jun 22, 2009
    #7
  8. Cor Ligthert[MVP] wrote:
    > Hans,
    >
    > Most people here are clever enough that they know that it is possible to
    > write, I take mostly the shortest notation when I want to show something.
    >
    > ("A".ToUpper() == "a".ToUpper())
    >
    > Cor
    >


    Why would you process the strings just to use one comparison, when there
    is another comparison that does exactly what you want without first
    processing the strings?

    --
    Göran Andersson
    _____
    http://www.guffa.com
    Göran Andersson, Jun 23, 2009
    #8
  9. Goran,

    Most people are clever enough to know what is done behind the scene.

    Strings to Upper doesn't process the string, it only takes a subset of the
    ascii code, it does not work by instance with the Turkish uppercase i.

    Cor


    "Göran Andersson" <> wrote in message
    news:%...
    > Cor Ligthert[MVP] wrote:
    >> Hans,
    >>
    >> Most people here are clever enough that they know that it is possible to
    >> write, I take mostly the shortest notation when I want to show something.
    >>
    >> ("A".ToUpper() == "a".ToUpper())
    >>
    >> Cor
    >>

    >
    > Why would you process the strings just to use one comparison, when there
    > is another comparison that does exactly what you want without first
    > processing the strings?
    >
    > --
    > Göran Andersson
    > _____
    > http://www.guffa.com
    Cor Ligthert[MVP], Jun 24, 2009
    #9
  10. Cor Ligthert[MVP] wrote:
    > Most people are clever enough to know what is done behind the scene.
    >

    Those people shouldn't propagate techniques they should know are bad.

    > Strings to Upper doesn't process the string,


    What Göran meant is that .ToUpper() creates a new string, which is then
    compared. Using .Equals() with a StringComparison saves you a string
    creation (or two) because it compares character-by-character (and it skips
    the comparison altogether if the lengths differ).

    In short: never use .ToUpper() (or .ToLower()) to compare strings in a
    case-insensitive manner. It's strictly worse than using .Equals() with the
    appropriate StringComparison flag.

    Yes, even if you think it doesn't look as nice. And even (or actually
    *especially*) for demonstration code.

    --
    J.
    Jeroen Mostert, Jun 24, 2009
    #10
  11. Smithers

    Merk Guest

    RE
    > Most people are clever enough to know what is done behind the scene.



    No - they are not!

    "Most people" can't even, well, I better stop right there...
    Merk, Jun 24, 2009
    #11
  12. Cor Ligthert[MVP] wrote:
    > Goran,
    >
    > Most people are clever enough to know what is done behind the scene.


    What do you mean by that?

    > Strings to Upper doesn't process the string,


    Of course it does. A method that just returns the same string without
    doing anything would be pretty useless, would it not?

    > it only takes a subset of
    > the ascii code, it does not work by instance with the Turkish uppercase i.


    How is that relevant?

    --
    Göran Andersson
    _____
    http://www.guffa.com
    Göran Andersson, Jun 26, 2009
    #12
  13. "Göran Andersson" <> wrote in message
    news:...
    > Cor Ligthert[MVP] wrote:
    >> Goran,
    >>
    >> Most people are clever enough to know what is done behind the scene.

    >
    > What do you mean by that?
    >
    >> Strings to Upper doesn't process the string,

    >
    > Of course it does. A method that just returns the same string without
    > doing anything would be pretty useless, would it not?
    >
    >> it only takes a subset of the ascii code, it does not work by instance
    >> with the Turkish uppercase i.

    >
    > How is that relevant?


    There exist strings a, b, c, and d for which

    a.ToUpper() == b.ToUpper() but string.Equal(a,b,IgnoreCase) is false

    c.ToUpper() != d.ToUpper() but string.Equal(c,d,IgnoreCase) is true

    >
    > --
    > Göran Andersson
    > _____
    > http://www.guffa.com
    >
    > __________ Information from ESET NOD32 Antivirus, version of virus
    > signature database 4221 (20090706) __________
    >
    > The message was checked by ESET NOD32 Antivirus.
    >
    > http://www.eset.com
    >
    >
    >


    __________ Information from ESET NOD32 Antivirus, version of virus signature database 4221 (20090706) __________

    The message was checked by ESET NOD32 Antivirus.

    http://www.eset.com
    Ben Voigt [C++ MVP], Jul 7, 2009
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Edward A Thompson
    Replies:
    4
    Views:
    529
    Tony Morris
    Feb 11, 2004
  2. Replies:
    5
    Views:
    1,241
    Tony Morris
    Apr 26, 2006
  3. Simple Simon

    Valgrind errors: valid, or false positives ?

    Simple Simon, Nov 4, 2006, in forum: C Programming
    Replies:
    4
    Views:
    417
    Simple Simon
    Nov 4, 2006
  4. Chanchal
    Replies:
    10
    Views:
    1,366
    Kevin McMurtrie
    Aug 24, 2009
  5. RichardOnRails

    False positives in editing data

    RichardOnRails, Nov 19, 2007, in forum: Ruby
    Replies:
    38
    Views:
    345
    RichardOnRails
    Nov 29, 2007
Loading...

Share This Page