2011-04-25 5 views
7

컨텍스트 : WPF로 WinForms 앱을 변환 (아마도)하기위한 준비 과정에서 프로토 타이핑 중입니다.이것이 == 비교가 실패한 근본적인 이유는 무엇입니까? (놀랄만 한 결과)

내가하는 코드는 매우 단순 트리 뷰 이벤트 핸들러를합니다

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> 

채워지지만 == 비교는 위의 두 번째 코드 줄에서 실패했습니다.

질문 : 왜했다가없이 컴파일 또는 런타임 오류

디버거

이 표시? (동일한 질문 다른 방법 : 실제로 비교되는 그러한 어떤 == 연산자 출력 FALSE는?)

enter image description here

답변

4

먼저 Tagstring으로 전송하십시오. object의 기본 구현에서 ==은 참조를 비교합니다. Tag 속성은 object 유형이므로 object 구현 인 objectstring 사이의 최저 공통 == 연산자를 사용하고 있습니다. Tagstring으로 캐스팅하면 값 비교 인 string의 구현이 사용됩니다. 당신이 treeViewItemTag의 유형을 보면

+0

고맙습니다. 그 정도의 세부적인 수준이었습니다. –

+0

사소한 세부 정보 : 문자열 비교는 먼저 참조 비교를 수행 한 다음 값 비교를 수행하도록 최적화되어 있습니다. –

+0

사소한 세부 사항 추가 : 문자열 인턴하기 때문입니다. – Femaref

1

사용 같음() 문자열을 비교한다.

업데이트 : 또는 둘 모두를 문자열로 전송하십시오. MSDN에서 예 :

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

제 1 비교 true를 반환하지만 거짓 제 반환 (이 참조 아닌 문자열을 비교하기 때문에).

+0

더 많은 Java 접근 방식입니다. 두 개의 문자열을 비교하면 == 연산자가 값의 동일성을 테스트하기 위해 오버로드됩니다. –

+0

slavik, 보통 당신이 옳을 것이지만,이 경우에 당신은 틀립니다. var는 type string이 아닌 object {string} 유형입니다. 따라서이 경우 과부하가 작동하지 않습니다. – invalidsyntax

+0

@ slavik262, 나는 동의해야합니다. 두 값이 모두 문자열 유형이면 괜찮습니다. 그러나 하나가 문자열이고 다른 하나가 객체 인 경우 ==를 사용하여 비교할 경우 참조를 비교할 수 없습니다. (그리고 놓치기 쉬운 컴파일러의 경고). String.Equals()를 호출하는 경우에는 발생하지 않습니다. 또한 == 연산자를 사용하여 비교 옵션을 지정할 수 없습니다. – Dmitry

4

사용 Object.Equals(treeViewItemTag, "ViewForAMs") 대신

+0

+1 이것은 나에게 (imho) 가장 깨끗한 최종 결과 코드를 제공합니다. –

2

, 당신은 유형의 객체가 아닌 문자열 것을 볼 수 있습니다. 따라서 ==를 사용하면 두 객체의 참조를 비교하게됩니다. 이 경우에는 항상 false가 반환됩니다. 대신 Equals()를 사용하거나 문자열로 변환하면 작동합니다.

1

TreeViewItem 속성의 태그는 문자열이 아니라 객체입니다. ==는 객체 참조를 비교합니다. 문자열을 비교하려면 비교하여 ToString() 수행해야합니다

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

을하지만 당신은 문자열이나 다른 비교는 실패가 포함되어 있는지 확인해야합니다.

0

'treeViewItem.Tag'는 Object에 대한 참조입니다. 기본적으로 C#에서 == 연산자는 참조 평등을 확인합니다. 즉, 두 객체가 메모리에서 동일하고 동일하다는 것을 확인합니다. String에는 '=='연산자가 오버로드되어 값의 동일성을 검사합니다. 즉, 문자열에 동일한 내용이 포함되어 있는지 확인합니다. 그래도 사용하려면 'treeViewItem.Tag'를 문자열로 캐스팅해야합니다.

0

저는 WPF에 익숙하지 않지만 Winforms 컨텍스트에서는 태그가 Object 유형이라고 말했을 것입니다.
Object의 항등 연산자는 참조를 비교합니다.

(또는 다른 독자)이 여전히 어떤 경우에 작동 이유를 알고 할 수 있습니다 경우

: 당신은 모두 StringBuilder 또는 관리되지 않는 기능의 수단을 통해 문자열을 구축
, 당신은 so.called 인턴 문자열을하지 않습니다. 즉, 런타임에 동일한 내용을 가진 두 개의 별개의 문자열 객체가있는 방법이 있습니다.
일반적으로 문자열은 위에서 설명한 것처럼 런타임시 빌드되는 경우를 제외하고 동일한 인스턴스를 참조합니다. String.Internet을 호출하여 동일한 내용의 문자열에 대한 인턴 참조를 얻을 수 있습니다. 그것들은 동일한 내용에 대해 동일한 인스턴스로 묶여 있습니다. 이 작은 세부 사항을 아는 것이 큰 도움이되거나 눈을 뜨게 할 수있는 상황이 있습니다.

관련 문제