2010-07-20 18 views
9

मैं एक साधारण क्लैंप बनाने के लिए कोशिश कर रहा हूँ (ताकि मैं कुछ भी तुलनीय के मूल्यों के लिए बाध्य कर सकते हैं ... ज्यादातर इस तरह के पूर्णांक, डबल, आदि के रूप में संख्या प्रकार के लिए)असंभव जेनेरिक प्रकार IComparable के साथ प्रयोग किया जाता है। क्या यह संभव है?

समस्या है, तो मुझे क्या करना है निम्नलिखित मुझे एक त्रुटि मिलती है, लेकिन according to MSDN आईसीओम्पेर्बल की तुलना करने के लिए शून्य मानों को संभालने में सक्षम होना चाहिए।
उद्धरण: "परिभाषा के अनुसार, कोई वस्तु शून्य से अधिक की तुलना करती है, और दो शून्य संदर्भ एक-दूसरे के बराबर तुलना करते हैं।"

public static T Clamp<T>(this T value, T min, T max) 
    where T : IComparable<T> 
{ 
    if (value.CompareTo(max) > 0) 
     return max; 

    if (value.CompareTo(min) < 0) 
     return min; 

    return value; 
} 



private Int32? _zip; 
public Int32? Zip 
{ 
    get 
    { 
     return _zip; 
    } 
    set 
    { 
     _zip = value.Clamp<Int32?>(0, 99999); 
    } 
} 

उत्तर

7

याद रखें, Int32?Nullable<Int32> के लिए एक आशुलिपि है। चूंकि Nullable<T>IComparable<T> लागू नहीं करता है, इसलिए आपका कोड, संरचित के रूप में संकलित नहीं होगा।

हालांकि, आप विधि ओवरलोड कर सकते हैं:

public static T? Clamp<T>(this T? value, T? min, T? max) 
    where T : struct, IComparable<T> 
{ 
    // your logic... 
} 
बेशक

, अगर आप व्यर्थ के साथ काम करने की योजना बना रहे हैं, तो आप कैसे आप null मूल्यों क्लैंप जाएगा परिभाषित करने के लिए है ...

आप वास्तव में null मूल्यों क्लैंप की जरूरत नहीं है, तो यह आसान हो सकता अशक्त के लिए सिर्फ पहला चेक अपनी संपत्ति गेटर में करने के लिए:

public Int32? Zip 
{ 
    ... 
    set 
    { 
     _zip = value == null ? value : value.Value.Clamp<Int32>(0,99999); 
    } 
,210

या बेहतर अभी तक, @LBushkin Nullable < टी> या टी के कहे अनुसार यह Clamp करने के लिए अतिरिक्त अधिभार के कार्यान्वयन का हिस्सा

+0

मुझे यकीन नहीं है कि मैंने ऐसा क्यों नहीं किया (मूल्य == शून्य)? मान: value.Clamp (0, 99 999); शुरुआत के लिए। मुझे लगता है कि मैं क्लैंप को स्वचालित रूप से करने के लिए मजबूर करने की कोशिश कर रहा था। लेकिन हां, यह वास्तव में इसे समझने के लिए और अधिक समझ में आता है क्योंकि यह क्लैंपिंग है। –

+0

और अब यह स्ट्रिंग के लिए काम नहीं करेगा)) –

12

बनाने ...? IComparable इंटरफ़ेस लागू नहीं करता है। दिया गया समाधान ठीक है, हालांकि मैं Single Responsibility Principle के बाद, उस मामले में एक विशेष वर्ग के अंदर तर्कसंगत तुलनात्मक तर्क पसंद करना पसंद करता हूं, और किसी भी निरर्थक प्रकार की तुलना करने के लिए भी इसका उपयोग किया जा सकता है।

उदाहरण के लिए, अगर आप इस तरह एक सामान्य Nullable प्रकार comparer वर्ग बना सकते हैं: अपने सहायकों में बचाने के लिए

public static T? Clamp<T>(this T? value, T? min, T? max) 
    where T : struct 
{ 
    var comparer = new NullableComparer<T>(); 

    if (comparer.Compare(value, max) > 0) 
     return max; 

    if (comparer.Compare(value, min) < 0) 
     return min; 

    return value; 
} 

हैंडी: आप इस तरह इस वर्ग का प्रयोग करेंगे

public class NullableComparer<T> : IComparer<Nullable<T>> 
     where T : struct, IComparable<T> 
{ 

    public int Compare(Nullable<T> x, Nullable<T> y) 
    { 
     //Compare nulls acording MSDN specification 

     //Two nulls are equal 
     if (!x.HasValue && !y.HasValue) 
      return 0; 

     //Any object is greater than null 
     if (x.HasValue && !y.HasValue) 
      return 1; 

     if (y.HasValue && !x.HasValue) 
      return -1; 

     //Otherwise compare the two values 
     return x.Value.CompareTo(y.Value); 
    } 

} 

इस मामले में पुस्तकालय।

उम्मीद है कि यह मदद करता है!