2011-04-25 14 views
7

संदर्भ: मैं अपने WinForms ऐप को WPF में परिवर्तित करने के लिए (शायद) के लिए prep में प्रोटोटाइप कर रहा हूं।यह अंतर्निहित कारण क्या है == तुलना विफल हो जाती है? (मेरे लिए आश्चर्यजनक परिणाम)

मैं बहुत ही सरल ट्री व्यू ईवेंट हैंडलर बनाने जिसके लिए कोड है:

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> 

जब मैंने इसे भाग गया, मैं पूरी तरह से मेरे डेटा ग्रिड को देखने के लिए उम्मीद पॉप्युलेट प्राप्त करें लेकिन == तुलना उपरोक्त कोड की दूसरी पंक्ति पर विफल रही है।

प्रश्न:: क्यों वहाँ थे कोई संकलन या क्रम त्रुटियों

डिबगर यह दिखाता है? (वही सवाल एक और तरीका: क्या वास्तव में इस तरह की तुलना में किया जा रहा है कि == ऑपरेटर आउटपुट गलत?)

enter image description here

उत्तर

4

Tag से string पहले कास्ट करें। object पर डिफ़ॉल्ट कार्यान्वयन में, == संदर्भों की तुलना करता है। Tag संपत्ति object प्रकार है, यह object और string के बीच सबसे कम सामान्य == ऑपरेटर का उपयोग कर रहा है, जो object कार्यान्वयन है। Tag से string कास्टिंग करके, string पर कार्यान्वयन का उपयोग किया जाता है, जो एक मूल्य तुलना है।

+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); 

पहले तुलना सच देता है, लेकिन दूसरे रिटर्न झूठी (क्योंकि यह संदर्भ, नहीं तार तुलना)।

+0

यह जावा दृष्टिकोण का अधिक है। दो तारों के बीच तुलना में == ऑपरेटर मूल्य समानता के परीक्षण के लिए अधिभारित होता है। –

+0

स्लाव, आमतौर पर आप सही होंगे, लेकिन इस मामले में आप गलत हैं। var प्रकार ऑब्जेक्ट {string} है, प्रकार स्ट्रिंग का नहीं है। तो, अधिभार इस मामले में काम नहीं करता है। – invalidsyntax

+0

@ slavik262, मुझे असहमत होना है। यह ठीक है जब दोनों मान स्ट्रिंग प्रकार के होते हैं। लेकिन अगर कोई स्ट्रिंग है और दूसरा ऑब्जेक्ट है, तो आप संदर्भों की तुलना समाप्त कर देंगे यदि आप == का उपयोग कर तुलना कर रहे हैं। (और संकलक से एक चेतावनी जो याद करने में आसान है)। यदि आप String.Equals() को कॉल कर रहे हैं तो ऐसा नहीं होगा। इसके अलावा आप == ऑपरेटर के साथ तुलना विकल्प निर्दिष्ट नहीं कर सकते हैं। – Dmitry

4

उपयोग Object.Equals(treeViewItemTag, "ViewForAMs") बजाय

+0

+1 यह मुझे (imho) साफ अंत परिणाम कोड के अनुसार देता है –

2

आप treeViewItemTag के प्रकार को देखें, तो आप उस प्रकार वस्तु, नहीं स्ट्रिंग है देखेंगे। तो जब आप == का उपयोग करते हैं, तो आप दो ऑब्जेक्ट्स के संदर्भों की तुलना कर रहे हैं। यह हमेशा इस मामले में झूठी वापसी करेगा। यदि आप इसके बजाए बराबर() का उपयोग करते हैं, या स्ट्रिंग में डालते हैं, तो इसे काम करना चाहिए।

1

TreeViewItem प्रॉपर्टी में टैग एक ऑब्जेक्ट है, स्ट्रिंग नहीं। == वस्तु संदर्भों की तुलना कर रहा है। स्ट्रिंग तुलना करने के लिए, आप तुलना का उपयोग कर toString() करना चाहिए:

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

लेकिन आप यकीन है कि एक स्ट्रिंग वरना तुलना भी असफल हो जायेगी शामिल होना है।

0

'treeViewItem.Tag' किसी ऑब्जेक्ट का संदर्भ है। डिफ़ॉल्ट रूप से सी # में, == ऑपरेटर संदर्भ समानता के लिए जांच करता है, यानी, कि दो ऑब्जेक्ट एक हैं और स्मृति में समान हैं। स्ट्रिंग में मूल्य समानता की जांच करने के लिए '==' ऑपरेटर ओवरलोड किया गया है, यानी, यदि तारों में एक ही सामग्री होती है। हालांकि इसका उपयोग करने के लिए, आपको स्ट्रिंग में 'treeViewItem.Tag' डालना होगा।

0

मैं WPF के साथ धाराप्रवाह नहीं हूं, लेकिन विनफॉर्म संदर्भ में, मैंने कहा होगा कि टैग ऑब्जेक्ट प्रकार है।
ऑब्जेक्ट पर समानता ऑपरेटर संदर्भों की तुलना करता है।

आप (या कुछ अन्य पाठक) को पता है क्यों यह अभी भी कुछ मामलों में काम करता है चाहते हो सकता है, तो:
जब आप StringBuilder या अप्रबंधित कार्यों के साधनों के माध्यम से तार का निर्माण किया है, तो आप एक so.called प्रशिक्षु स्ट्रिंग नहीं मिलता है। इसका मतलब है कि, एक तरीका है कि आपके पास रनटाइम पर दो अलग स्ट्रिंग ऑब्जेक्ट्स हैं जिनकी एक ही सामग्री है।
आमतौर पर, स्ट्रिंग्स एक ही उदाहरण को संदर्भित करते हैं, सिवाय इसके कि जब वे उपरोक्त समझाए गए रनटाइम पर बनाए जाते हैं। आप एक ही सामग्री के साथ एक स्ट्रिंग का आंतरिक संदर्भ प्राप्त करने के लिए String.Intern को कॉल कर सकते हैं। वे एक ही सामग्री के लिए एक ही उदाहरण होने के लिए बाध्य हैं। ऐसी स्थितियां हैं जहां इस छोटे से विस्तार को जानना एक बड़ी मदद या आंख खोलने वाला हो सकता है।

संबंधित मुद्दे

 संबंधित मुद्दे