7

コンテキスト:WinFormsアプリをWPFに変換するための準備としてプロトタイピングを行っています。

コードが次のような非常に単純なツリービューイベントハンドラーを作成します。

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();
}

XAMLは次のとおりです。

<Window x:Class="AccountingWpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        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>

それを実行したとき、データグリッドにデータが入力されることを完全に期待していましたが、上記のコードの2行目で==比較が失敗しました。

デバッガーはこれを示します:

質問:コンパイルエラーやランタイムエラーが発生しなかったのはなぜですか?(同じ質問を別の方法で:==演算子がFALSEを出力するように実際に何が比較されていますか?)

ここに画像の説明を入力してください

4

7 に答える 7

4

最初にキャストしTagますstring。のデフォルトの実装ではobject==参照を比較します。Tagプロパティはタイプであるため、実装であるとの間でobject最も低い共通==演算子を使用しています。にキャストすることにより、値の比較であるonの実装が使用されます。objectstringobjectTagstringstring

于 2011-04-25T18:53:03.730 に答える
4

Object.Equals(treeViewItemTag, "ViewForAMs")代わりに使用してください

于 2011-04-25T18:54:05.340 に答える
2

treeViewItemTagのタイプを見ると、タイプが文字列ではなくオブジェクトであることがわかります。したがって、==を使用すると、2つのオブジェクトの参照を比較することになります。この場合、常にfalseが返されます。代わりにEquals()を使用するか、文字列にキャストすると、機能するはずです。

于 2011-04-25T18:54:19.053 に答える
1

Equals()を使用して文字列を比較します。

更新:または両方を文字列にキャストします。MSDNの例:

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

最初の比較はtrueを返しますが、2番目の比較はfalseを返します(文字列ではなく参照を比較するため)。

于 2011-04-25T18:51:02.197 に答える
1

TreeViewItemプロパティのタグはオブジェクトであり、文字列ではありません。==はオブジェクト参照を比較しています。文字列を比較するには、ToString()を使用して比較を行う必要があります。

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

ただし、文字列が含まれていることを確認する必要があります。含まれていないと、比較も失敗します。

于 2011-04-25T18:54:58.023 に答える
0

'treeViewItem.Tag'はオブジェクトへの参照です。C#のデフォルトでは、==演算子は参照の同等性をチェックします。つまり、2つのオブジェクトがメモリ内で同一であるかどうかをチェックします。文字列には、値が等しいかどうか、つまり文字列に同じ内容が含まれているかどうかを確認するために、'=='演算子がオーバーロードされています。ただし、これを使用するには、「treeViewItem.Tag」を文字列にキャストする必要があります。

于 2011-04-25T18:55:10.250 に答える
0

私はWPFに精通していませんが、Winformsのコンテキストでは、TagはObject型であると言っていたでしょう。
Objectの等式演算子は、参照を比較します。

あなた(または他の読者)が、なぜこれがまだ機能するのかを知りたい場合:
StringBuilderまたはアンマネージ関数を使用して文字列を作成した場合、いわゆるインターン文字列は取得されません。つまり、実行時に同じコンテンツを持つ2つの異なる文字列オブジェクトを作成する方法があります。
通常、文字列は、上記で説明したように実行時に作成される場合を除いて、同じインスタンスを参照します。String.Internを呼び出して、同じ内容の文字列のインターン参照を取得できます。それらは、同じコンテンツの同じインスタンスである必要があります。この小さな詳細を知ることは、大きな助けまたは目を見張る可能性がある状況があります。

于 2011-04-25T18:59:04.883 に答える