हस्ताक्षर परिवर्तन पर संकलन त्रुटि को कैसे सुनिश्चित करें जहां 'पैराम्स' कीवर्ड का उपयोग किया जाता है

मेरे पास इस तरह की एक विधि है:

public void Foo(params string[] args) {
  bar(args[0]); 
  bar(args[1]);
}

नई आवश्यकताओं को इस तरह के बदलाव की ओर ले जाता है:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    bar(args[0]); 
    bar(args[1]);
  }
}

समस्या यह है कि भले ही मैंने विधि हस्ताक्षर बदल दिया हो, फिर भी कोई संकलन त्रुटियां नहीं होतीं, जो कि सही है, लेकिन मैं चाहता हूं कि प्रत्येक कॉल के लिए Foo विधि पर संकलन त्रुटियां हों जहां तर्क < कोड> बाज़ निर्दिष्ट नहीं किया गया है। यही है, यदि परिवर्तन से पहले Foo पर कॉल किया गया था तो यह एक था:

Foo(p1,p2); //where p1 and p2 are strings

अब यह एक होना चाहिए:

Foo(baz,p1,p2);

अगर इसे इस तरह से बदला नहीं जाएगा, p1 को baz पर असाइन किया जाएगा, और पैराम्स सरणी args लंबाई 1 होगी और एक OutOfBounds अपवाद फेंक दिया जाएगा।

हस्ताक्षर बदलने और यह सुनिश्चित करने का सबसे अच्छा तरीका क्या है कि सभी कॉलिंग कोड तदनुसार अपडेट किया गया है? (असली परिदृश्य वह जगह है जहां Foo एक बिल्डिंग सर्वर पर स्वचालित रूप से बनाई गई कई परियोजनाओं द्वारा साझा की गई असेंबली में रहता है। एक संकलन त्रुटि इस प्रकार सभी कोड का पता लगाने का एक आसान तरीका होगा जिसे समायोजित करने के लिए स्पर्श किया जाना चाहिए बदलाव।)

Edit: As Daniel Mann and others pointed out, the example above suggests that I should not use params at all. So I should explain that in my real world example it's not always the case that args needs to have two elements, as far as the logic in Foo is concerned args can contain any number of elements. So let's say this is Foo:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    int x = GetANumberDynamically();
    for(int i = 0; i
0
क्या करें @ ओन्ड्रेज जेनेसेक सुझाव देता है। यह निश्चित रूप से सबसे अच्छा तरीका है।
जोड़ा लेखक dav_i, स्रोत
हस्ताक्षर को पूरी तरह से अलग करने के लिए क्यों नहीं बदलें (जैसे int या कुछ लेना)। फिर सभी विधियों पर एक संकलन त्रुटि फेंक दी जाएगी? बेशक एक बेहतर तरीका Resharper या इसी तरह के साथ refactor होगा।
जोड़ा लेखक dav_i, स्रोत
@NobodysNightmare असल में नहीं, यह सिर्फ प्रदूषित उदाहरण है। मुझे यह समझा जाना चाहिए था। फू के संदर्भ से यह ज्ञात नहीं है कि अपवाद से बचने के लिए कितने पैरा-पैरामीटर तर्कों में शामिल होना चाहिए।
जोड़ा लेखक tyrone copex, स्रोत
@dav_i कारण मुझे यह पसंद नहीं है कि निर्भर परियोजनाओं के लिए रखरखाव विभिन्न व्यक्तियों पर फैल गया है। अगर अचानक हस्ताक्षर में int के कारण उन्हें अपनी मेज पर बिल्ड त्रुटि मिलती है तो यह भ्रमित हो सकती है और स्पष्ट नहीं है कि उन्हें क्या करना है। जो मैं चाहता हूं वह एक संकलन त्रुटि है जिसके लिए एक समाधान की आवश्यकता होती है जो स्थायी समाधान है। लेकिन अगर यह प्राप्त नहीं किया जा रहा है तो मुझे लगता है कि मैं आपके सुझाव के साथ जाऊंगा।
जोड़ा लेखक tyrone copex, स्रोत
@dav_i में जोड़ने के लिए: यदि आप पहले string के बजाय int जोड़ें, संकलित करें, सभी कॉलिंग कोड संशोधित करें, फिर <कोड बदलें > int string पर। यह भी ध्यान रखें कि if ("do bar" .quals (baz)) { वास्तव में एक बुरा उदाहरण है, ऐसा लगता है कि एक और ओवरलोड या अधिक रिफैक्टरिंग की आवश्यकता है।
जोड़ा लेखक CodeCaster, स्रोत
बस यह सुनिश्चित करने के लिए: क्या आपके पैरा-पैरामीटर को वास्तव में दो इनपुट या कम से कम दो इनपुट की आवश्यकता है? पूर्व मामले में मैं सुझाव देता हूं कि बिल्कुल पैरा का उपयोग न करें ...
जोड़ा लेखक NobodysNightmare, स्रोत

2 उत्तर

यहां समाधान है। पूर्व विधि हस्ताक्षर को न बदलें, निर्दिष्ट दोनों तर्कों के साथ बस अप्रचलित विशेषता जोड़ें।

[Obsolete("Use Foo(string, params string[]) version instead of this", true)]
public void Foo(params string[] args) {
  bar(args[0]); 
  bar(args[1]);
}

फिर एक नए हस्ताक्षर के साथ एक नई विधि बनाएँ।

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    bar(args[0]); 
    bar(args[1]);
  }
}

अप्रचलित विशेषता में दूसरा तर्क एक संकलन त्रुटि सुनिश्चित करता है। इसके बिना यह सिर्फ एक संकलन चेतावनी का कारण बनता है। विशेषता के बारे में अधिक जानकारी MSDN पर उपलब्ध है

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

नीचे टिप्पणियों में चर्चा के आधार पर, डैनियल मान एक दिलचस्प समस्या के साथ आया था।

इससे समस्या हल नहीं होगी। अगर आप फू ("ए", "बी") कहते हैं तो क्या होगा? उस स्थिति में, यह अभी भी गैर-अप्रचलित विधि को केवल दो तर्कों के साथ कॉल करेगा, और एक ही समस्या का कारण बन जाएगा।

मैं यह जांचने की सलाह दूंगा कि bar को कॉल करने से पहले args के माध्यम से एक तर्क पारित किया गया है या नहीं।

0
जोड़ा
मैं नया पैरामीटर बाज़ प्रदान करने के लिए कॉलिंग कोड को कैसे लागू करना है, इस बारे में प्राप्त करने का प्रयास कर रहा हूं। मैं नहीं देखता कि फू के भीतर चेक जोड़कर इसे कैसे हल किया जाएगा।
जोड़ा लेखक tyrone copex, स्रोत
इनपुट के लिए धन्यवाद। जैसा कि बताया गया है कि यह दिए गए उदाहरण को हल नहीं करता है: दो स्ट्रिंग्स के साथ फू को कॉल करना।
जोड़ा लेखक tyrone copex, स्रोत
खैर, यह अक्सर नहीं है कि मैं हर कोने के मामले के साथ आते हैं। यही कारण है कि अन्य लोग और टिप्पणियां हैं। मैं उचित उत्तर अपडेट कर दूंगा, और आपको इंगित करने के लिए धन्यवाद।
जोड़ा लेखक Ondrej Janacek, स्रोत
प्रश्न का मेरा संपादन हिस्सा पढ़ें। प्रश्न में इस समस्या के बावजूद, आपको प्रदत्त तर्कों की संख्या पर भरोसा नहीं करना चाहिए। इसका उपयोग करने से पहले इसे जांचना बेहतर है। मेरा मानना ​​है कि तर्कों की संख्या की जांच के साथ मेरे समाधान का संयोजन समाधान प्रदान करता है।
जोड़ा लेखक Ondrej Janacek, स्रोत
हाँ, लेकिन यह मेरी समस्या नहीं है। यह सिर्फ एक खराब डिजाइन है जहां ओपी मानता है कि args के माध्यम से हमेशा दो तर्क पारित किए जाएंगे।
जोड़ा लेखक Ondrej Janacek, स्रोत
यह आपकी समस्या है क्योंकि आपके द्वारा दिए गए उत्तर वास्तव में प्रश्न का उत्तर नहीं देते हैं।
जोड़ा लेखक Daniel Mann, स्रोत
हां, यह नया अधिभार चुन देगा, और उसके बाद args सरणी में केवल एक आइटम होगा, जो अभी भी प्रदान किए गए उदाहरण में रनटाइम त्रुटि का कारण बन रहा है। मूल सवाल इस तरह की समस्या से बचने के बारे में था।
जोड़ा लेखक Daniel Mann, स्रोत
इससे समस्या हल नहीं होगी। यदि आप Foo ("a", "b") को कॉल करते हैं तो इसके बारे में क्या? उस स्थिति में, यह अभी भी गैर-अप्रचलित विधि को केवल दो तर्कों के साथ कॉल करेगा, और एक ही समस्या का कारण बन जाएगा।
जोड़ा लेखक Daniel Mann, स्रोत

यदि आपके पास आवश्यक पैरामीटर हैं तो पैरा कीवर्ड का उपयोग न करना सबसे आसान समाधान है।

जाहिर है, आप कम से कम दो पैरामीटर रखने के लिए args की अपेक्षा कर रहे हैं। यह कहना सुरक्षित है कि उनको जरूरी है। इस तरह एक विधि हस्ताक्षर क्यों नहीं है?

<कोड> सार्वजनिक शून्य फू (स्ट्रिंग बाज़, स्ट्रिंग आवश्यकअर्ग्यूमेंट 1, स्ट्रिंग आवश्यकअर्ग्यूमेंट 2, पैराम स्ट्रिंग [] वैकल्पिक आर्टमेंट्स)

यह अस्पष्टता को हटा देता है: यह हमेशा कम से कम 3 तर्कों की आवश्यकता होगी।

एक अन्य विकल्प जिसे मैंने किसी कारण से नहीं सोचा था, नामित पैरामीटर का उपयोग करना है। जाहिर है, आपके सभी कोड को स्पष्ट रूप से ऐसा करना होगा, लेकिन आप यह कर सकते हैं:

<कोड> फू (बाज़: "बार", तर्क: नया [] {"ए", "बी", "सी"});

0
जोड़ा
@JunWeiLee यह अलग-अलग संदर्भों को संभालता नहीं है, केवल गतिशील है। वास्तविक उपयोग ऐसा है कि पैराम स्ट्रिंग [] तर्क एक क्वेरी में पैरामीटर होने का अंत होता है। कौन सी क्वेरी/पैरामीटर की संख्या केवल रनटाइम पर जानी जाती है।
जोड़ा लेखक tyrone copex, स्रोत
आप मेरे डमी कोड उदाहरण के बारे में पूरी तरह से सही हैं। दुर्भाग्य से मेरे असली दुनिया के उदाहरण में यह फू के संदर्भ से ज्ञात नहीं है कि कितने तारों की आवश्यकता है। (तर्कों को उन प्रश्नों के पैरामीटर के लिए उपयोग किया जाता है जो गतिशील रूप से लोड होते हैं।)
जोड़ा लेखक tyrone copex, स्रोत
यदि फू कई अलग-अलग संदर्भों को संभालता है, तो शायद यह बहुत अधिक कर रहा है? मुझे अभी भी लगता है कि विधि हस्ताक्षर का एक अधिक व्यापक नवीनीकरण की आवश्यकता हो सकती है। इस बिंदु पर शायद आप वास्तविक इच्छित उपयोग पर अधिक प्रकाश डाल सकते हैं
जोड़ा लेखक Jun Wei Lee, स्रोत