开发者

what's the underlying reason this == comparison fails? (surprising result for me)

开发者 https://www.devze.com 2023-02-28 20:03 出处:网络
Context: I am prototyping in prep for (maybe) converting my WinForms app to WPF. I make very simple tree view event handler for which the code is:

Context: I am prototyping in prep for (maybe) converting my WinForms app to WPF.

I make very simple tree view event handler for which the code is:

var treeViewItem = (TreeViewItem)e.NewValue;
var treeViewItemTag = treeViewItem.Tag;
if (treeViewItemTag == "ViewForAMs")
{
    ObjectQuery<AccountManagerView> oq = entities.AccountManagerViews;
    var q =
        from c in oq
        select c;
    dataGrid1.ItemsSource = q.ToList();
}

and the XAML is:

<Window x:Class="AccountingWpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/x开发者_开发问答aml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <DockPanel>
        <TreeView Name="treeView1" ItemsSource="{Binding Folders}"
          SelectedItemChanged="treeView1_SelectedItemChanged">
            <TreeViewItem Header="Account Manager View" Tag="ViewForAMs"/>
        </TreeView>
        <DataGrid AutoGenerateColumns="True" Name="dataGrid1" />
    </DockPanel>
</Window>

When I ran it, I fully expected to see my data grid get populated but the == comparison failed on the second line of code above.

The debugger shows this:

QUESTION: why were there no compile or runtime errors? (same question another way: what is actually being compared such that the == operator outputs FALSE?)

what's the underlying reason this == comparison fails? (surprising result for me)


Cast the Tag to string first. In the default implementation on object, == compares references. As the Tag property is of type object, it is using the lowest common == operator between object and string, which is the object implementation. By casting Tag to string, the implementation on string is used, which is a value comparision.


Use Object.Equals(treeViewItemTag, "ViewForAMs") instead


If you look at the type of treeViewItemTag, you will see that the type is object, not string. So when you use ==, you are comparing the references of two objects. That will always return false in this case. If you use Equals() instead, or cast to a string, then it should work.


The Tag in TreeViewItem property is an object, not a string. The == is comparing object references. To compare the string, you should do the comparison using ToString():

if (treeViewItemTag.ToString() == "ViewForAMs")

But you have to be sure contains a string or else the comparison will also fail.


Use Equals() to compare strings.

UPDATE: Or cast both to strings. An example from MSDN:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);

The first comparison returns true, but the second returns false (because it compares references, not strings).


'treeViewItem.Tag' is a reference to an Object. By default in C#, the == operator checks for reference equality, i.e., that the two objects are one and the same same in memory. String has the '==' operator overloaded to check for value equality, that is, if the strings contain the same contents. To use it though, you need to cast 'treeViewItem.Tag' to a string.


I am not fluent with WPF, but in a Winforms context, I would have said that Tag is of type Object.
The equality operator on Object compares references.

If you (or some other reader) might want to know why this still works in some cases:
When you built strings via means of StringBuilder or unmanaged functions, you do not get a so.called intern string. That means, that there is a way that you have two distinct string objects at runtime that have the same content.
Usually, Strings refer to the same instance, except when they are built at runtime like explained above. You can call String.Intern to get an intern reference of a string with the same content. Those are bound to be the same instance for the same content. There are situations where knowing this tiny detail can be a big help or eye-opener.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号