2009-02-11 14 views
10

मैं सिर्फक्या यह एक एक्सटेंशन मोड का अच्छा उपयोग है?

if (value == value1 || value == value2 || value == value3 || value == value4) 
    //do something 

की लाइनों में एक अगर बयान में लिखा था और यह मुझे गुस्सा दिलाती है मैं हमेशा 'मूल्य ==' भाग को दोहराने के लिए किया है। मेरी राय में यह पढ़ने में मुश्किल बनाने के अलावा कोई उद्देश्य नहीं दे रहा है।

public static bool IsEqualToAny<T>(this T value, params T[] objects) 
{ 
    return objects.Contains(value); 
} 

अब मैं बस लिख सकते हैं

if (value.IsEqualToAny(value1, value2, value3, value4)) 
    //do something 

यह एक ExtensionMethod का एक अच्छा उपयोग है:

मुझे लगता है कि उपरोक्त परिदृश्य अधिक पठनीय बनाना चाहिए निम्नलिखित ExtensionMethod लिखा?

संपादित करें:

सभी महान उत्तरों के लिए धन्यवाद। रिकॉर्ड के लिए: मैंने विधि को रखा है। जबकि सुझाव है कि आप बस new []{value1,value2,value3,value4}.Contains(value) इस्तेमाल कर सकते हैं सच है, मैं बस अगर बयान इस तरह पढ़ने का अधिकार (बाएं से अगर यह मान इनके बजाय में से किसी के बराबर है पसंद करते हैं इन मूल्यों का मान यही)। प्रत्येक ऑब्जेक्ट पर इंटेलिजेंस में एक और विधि दिखाई देने के लिए मेरे लिए कोई मुद्दा नहीं है।

उत्तर

4

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

जवाब है, "हाँ, यह है"

1

मुझे अच्छा लगता है, हालांकि यह थोड़ा अपरंपरागत लगता है।

1

यह बहुत उचित लगता है, लेकिन मैं एक कदम वापस ले जाऊंगा। क्या आप तुलना में कोई व्यवसाय अर्थ डाल सकते हैं? वो मूल्य क्या हैं? हो सकता है कि आप IsSpecialCustomerLocation नामक विधि से बेहतर हों या कुछ ऐसा जो कोड के वास्तविक उद्देश्य को व्यक्त करता हो।

+0

धन्यवाद। यह काफी सामान्य है। मैं सिर्फ एक enum मूल्य की तुलना कर रहा था - यह जीयूआई प्रोग्रामिंग से संबंधित था, इसलिए इसका कोई व्यवसाय अर्थ नहीं था। –

1

तुम भी LINQ विधि वाक्य रचना उस कार्य के लिए (System.Linq नाम स्थान का उपयोग करके) का उपयोग कर सकते हैं:

  object[] objects = new object[10]; 
     objects.Contains(new MyClass()); 

हम्म मुझे एक पल सोचते हैं ... ओह आप पहले से ही इसे प्रयोग। लेकिन आपने इसे सीधे कॉल करने के बजाय इसे एक अलग विधि में रखा है।

+0

यह हर बार करने के लिए बहुत अधिक काम है। –

+0

सरणी प्रारंभकर्ता वाक्यविन्यास भी क्लीनर होगा ... मेरी पोस्ट देखें। –

+0

आप सही हैं। इस बात से सहमत! – Alexander

5

यह एक अप्रतिबंधित T के लिए एक विस्तार विधि लिखने के लिए असामान्य है। कम से कम नहीं, यह दृष्टिकोण जल्दी से आपके इंटेलिजेंस को उपयोग करने में काफी कठिन बना देगा।

मान्य होने पर, मैं शायद को विस्तार विधि के रूप में टालना चाहूंगा - शायद मानक मानक उपयोगिता विधि का उपयोग करें।

सी # 3 सरणी प्रारंभकर्ता वाक्यविन्यास आसान हो सकता है?

bool isTrue = new[] { 1, 2, 3 }.Contains(3); 
बेशक

, डेटा के बड़े सेट के लिए, आप कैश करने के लिए एक HashSet<T> कहीं ;-p

+0

टिप्पणी मार्क के लिए धन्यवाद। क्या आप समझा सकते हैं कि यह इंटेलिजेंस का उपयोग करने में कठोर क्यों होगा? –

+0

क्योंकि जब आप "।" दबाते हैं तो यह प्रत्येक एकल चर पर दिखाई देगा। यह केवल कुछ तरीकों से कुछ तरीकों से प्रासंगिक तरीकों को खोजने में कठोर परिश्रम करना शुरू कर देता है ... वास्तव में, आप इस विधि का उपयोग नहीं करना चाहते हैं ** ** ** अक्सर (मुझे उम्मीद है) की तुलना में हर दूसरी विधि उपलब्ध है। –

+0

मुझे लगता है - अच्छा बिंदु। धन्यवाद। –

1

मैं उस उद्देश्य के लिए एक स्थिर वर्ग होगा चाहते हो सकता है।मुझे वह समाधान पसंद नहीं है क्योंकि यह सभी वर्गों के लिए एक विधि जोड़ता है जो थोड़ा अधिक लगता है। हालांकि यह ओओडी के साथ एक तरह से जाता है क्योंकि आप ऑब्जेक्ट्स को स्वयं पर काम करने के लिए कहते हैं (थोड़े)।

फिर भी, मैं इसके बजाय एक पुन: प्रयोज्य वर्ग के साथ जाऊंगा क्योंकि मैं देख सकता हूं कि एक एंटीपाटर कैसे बना सकता है। मैं इसे अभी तक एक एंटीपाटरन नहीं कह रहा हूं, लेकिन अगर उनमें से बहुत से लोग पॉप अप करते हैं तो मैं इसे पठनीयता की एंटीपार्टर्न कहूंगा क्योंकि प्रत्येक ऑब्जेक्ट विस्तार विधियों के साथ अव्यवस्थित हो जाएगा। मैं इसे नामस्थान प्रदूषण की तरह देखता हूं, लेकिन वर्ग सदस्य प्रदूषण।

if (ConditionHelper.IsEqualToAny(value, value1, value2, value3)) 
{ 
    // Do something 
} 

वही नौकरी करता है और कुछ भी प्रदूषित नहीं करता है।

+0

इसके बारे में सोचने के लिए आ रहा है, यह थोड़ा पठनीयता समस्या का सामना करना पड़ता है।इसके साथ ऐसा करना है कि यह स्पष्ट नहीं है कि मान 1, मान 2, मूल्य 3 और आगे के विरुद्ध मूल्य की जांच की जाती है। value.IsEqualToAny (value1, value2, value3) में बेहतर पठनीयता है। मेरी चिंता केवल प्रदूषण सदस्यों के बारे में थी। – Statement

1

क्या आप वास्तव में ऐसा करने का इरादा रखते हैं और गारंटी देते हैं कि आप आवेदन करेंगे पर सभी संभावित ऑब्जेक्ट्स जहां आप इस विस्तार विधि का उपयोग कर सकते हैं?

यदि कुछ दिए गए ऑब्जेक्ट ऑपरेटर == ओवरलोडिंग द्वारा समानता का परीक्षण करते हैं तो आपका सामान्य समाधान विफल हो जाएगा। यह एकाधिक == परीक्षणों के वास्तविक समकक्ष नहीं बनाता है। यह एक्सटेंशन विधियों को लिखने के खतरे का भी एक अच्छा उदाहरण है!

निम्नलिखित Linq कोड काम करता है जब आप के रूप में अच्छी ओवरलोडिंग ऑपरेटर को लागू के रूप में यदि आप डिफ़ॉल्ट का उपयोग कर रहे == वस्तु संदर्भ तुलना, यह कहना है कि मूल्य वास्तव में मान 1, 2, 3 या 4 के रूप में एक ही वस्तु है का मतलब, यह देखते हुए

V[] lv = { value, value2, value3, value4 }; 
if (lv.Any(v => v==value)) 
    // do something 

या एक छोटी हाथ संस्करण:

if (new List<V>{value, value2, value3, value4 }.Any(v => v==value)) 
    // do something 

मैं ऊपर लैम्ब्डा भाव एक सामान्य विस्तार विधि में काम करने के लिए नहीं मिल सका इस विशेष मामले में अपने मूल्यों का उद्देश्य प्रकार के रूप में वी ।

एक अच्छा (यदि अप्रासंगिक) मैं क्या सोचता हूँ एक सुंदर, पठनीय वाक्य रचना है के उदाहरण के रूप में, पायथन में मुहावरा

if value in (value1, value2, value3, value4): 
+0

मुझे नहीं लगता कि यह एक मुद्दा है। Contains विधि (जो एक ExtensionMethod है (System.Linq.Enumerable में कार्यान्वित)) एक समानता कॉम्पैयर का उपयोग करता है जो (डिफ़ॉल्ट मामले में) एक == तुलना का उपयोग करता है। –

+0

हो सकता है कि मैंने इसे गलत तरीके से कार्यान्वित किया हो या जिस तरह से यह बाध्य है, उसके बारे में कुछ है लेकिन जब मैं इसका परीक्षण करता हूं तो विस्तार विधि किसी ऑब्जेक्ट का पता लगाने में विफल होती है जो एक अलग वस्तु है लेकिन इसके ऑपरेटर == ओवरलोडिंग के आधार पर बराबर होती है। –

0

होगा यदि आप केवल एक Enum मूल्य की जाँच कर रहे हैं (जैसा कि आप में कहा रोजर्स उत्तर पर टिप्पणी), आपको Enum पर FlagsAttribute का उपयोग करना चाहिए।

[Flags] 
public enum Value 
{ 
    Value1 = 0, 
    Value2 = 1, 
    Value3 = 2, 
    Value4 = 4 
} 

Value value = Value.Value1; 
if (value | Value.Value1 | Value.Value2 | Value.Value3 | Value.Value4) 
{ 
    // You can also use other bitwise operations, like & (AND),^(XOR) and ~ (NOT) 
} 

अन्यथा; यदि यह डोमेन विशिष्ट है, तो इसे अपने व्यावसायिक तर्क में जोड़ें। यदि यह सामान्य है, तो एक सहायक वर्ग बनाएं।

+0

मुझे नहीं लगता कि यह उचित होगा। केवल इसलिए कि मैं कई अलग-अलग मूल्यों की जांच करना चाहता हूं, इसका मतलब यह नहीं है कि enum थोड़ा सा क्षेत्र होना चाहिए। मैं नहीं चाहता कि enum मान संयुक्त मूल्य हो। - हालांकि आपके इनपुट के लिए धन्यवाद। मैं थोड़ी देर के लिए इस विस्तार विधि का उपयोग कर रहा हूं और यह कई स्थितियों में काफी उपयोगी रहा है। –

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