2011-01-31 21 views
8

मैं सॉर्टिंग के लिए एक जेनेरिक ऑब्जेक्ट तुलनाकर्ता लिखने की कोशिश कर रहा हूं, लेकिन मैंने देखा है कि यह उस उदाहरण को संभाल नहीं करता है जहां इसकी तुलना की जाने वाली मानों में से एक शून्य है। जब कोई ऑब्जेक्ट शून्य होता है, तो मैं इसे खाली स्ट्रिंग के समान व्यवहार करना चाहता हूं। मैंने स्ट्रिंग को शून्य मानों को सेट करने का प्रयास किया है। लक्षण लेकिन फिर मुझे तुलनात्मक() पर कॉल करते समय "ऑब्जेक्ट टाइप स्ट्रिंग" होना चाहिए।मैं अपने जेनेरिक तुलनाकर्ता (आईसीओएमपेयर) को नल को कैसे संभाल सकता हूं?

public int Compare(T x, T y) 
{ 
    PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression); 
    IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null); 
    IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null); 

    if (obj1 == null) obj1 = String.Empty; // This doesn't work! 
    if (obj2 == null) obj2 = String.Empty; // This doesn't work! 

    if (SortDirection == SortDirection.Ascending) 
     return obj1.CompareTo(obj2); 
    else 
     return obj2.CompareTo(obj1); 
} 

मैं अब इस के साथ काफी अटक गया हूँ! किसी भी सहायता की सराहना की जाएगी।

उत्तर

15

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

if (obj1 == null && obj2 == null) 
    return 0; 
else if (obj1 == null) 
    return -1; 
else if (obj2 == null) 
    return 1; 
else 
    return obj1.CompareTo(obj2); 
+0

धन्यवाद एंथनी, यह एक इलाज करता है! मैं वास्तव में नहीं जानता कि मैं कभी भी सरल समाधान क्यों नहीं ढूंढता ... – NickG

0

के बाद से T एक सामान्य प्रकार है, आप इसे एक String मान निर्दिष्ट नहीं कर सकते हैं; आप इसे केवल T प्रकार का मान असाइन कर सकते हैं। यदि आप स्ट्रिंग की तुलना करने के लिए इसका उपयोग करने जा रहे हैं, तो T के बजाय String का उपयोग करें। अन्यथा, शून्य जांच जोड़ें और तय करें कि null क्रम में कहां गिरना चाहिए।

+0

है यही कारण है कि मैं (उत्तरार्द्ध) करने के लिए कोशिश कर रहा था, लेकिन मैं सिर्फ काम करने के लिए कुछ भी नहीं मिल सकता है के रूप में। मैं नहीं जानता कि शून्य के बजाए तुलना करने के लिए एक नया खाली मान्य टी ऑब्जेक्ट कैसे घोषित किया जाए। मैं अभी भी ईमानदार होने के लिए जेनेरिक द्वारा उलझन में हूँ! – NickG

+1

@ निक, एक संदर्भ प्रकार के लिए एक डिफ़ॉल्ट 'टी' अभी भी शून्य होगा। एक तत्काल लेकिन अन्यथा खाली 'टी' प्राप्त किया जा सकता है यदि' टी' में 'टी: नई()' बाधा थी, जो आपको अपनी विधि के अंदर 'टी' को चालू करने की अनुमति देगी, लेकिन इसका मतलब यह भी होगा कि सभी 'टी उम्मीदवारों को सार्वजनिक पैरामीटर रहित कन्स्ट्रक्टर होना होगा। इस विशेष स्थिति में, आपको यह आवश्यकता नहीं करनी चाहिए क्योंकि आपको अपने कोड में नल के साथ प्रभावी ढंग से निपटने में सक्षम होना चाहिए। –

0
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null) ?? ""; 
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null) ?? ""; 

यह मूलतः इसका मतलब है कि obj1 अब propertyInfo.GetValue (एक्स, नल) या, कि यदि अशक्त होने के लिए होता है, obj1 हो जाएगा "" का मान हो जाएगा।

या यदि समस्या यह है कि getValue अशक्त पर दुर्घटनाओं आप की तरह कुछ कर सकता है:

IComparable obj1 = ""; 
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {} 
1
if (SortDirection == SortDirection.Ascending) 
    return Comparer<T>.Default.Compare(obj1, obj2); 
else 
    return Comparer<T>.Default.Compare(obj2, obj1);