2012-01-26 16 views
29

मैं एक विधि, params कीवर्ड का उपयोग करता है तो तरह है:एक पैराम विधि के लिए नल गुजरने का परिणाम नल पैरामीटर सरणी में क्यों होता है?

private void ParamsMethod(params string[] args) 
{ 
    // Etc... 
} 

फिर, मैं विधि तर्क के विभिन्न संयोजनों का उपयोग कर फोन:

      // Within the method, args is... 
ParamsMethod();    // - a string array with no elements 
ParamsMethod(null);   // - null (Why is this?) 
ParamsMethod((string)null); // - a string array with one element: null 
ParamsMethod(null, null); // - a string array with two elements: null and null 
ParamsMethod("s1");   // - a string array with one element: "s1" 
ParamsMethod("s1", "s2"); // - a string array with two elements: "s1" and "s2" 

मैं मामलों के सभी समझते हैं, के अलावा दूसरा एक। क्या कोई बता सकता है कि क्यों ParamsMethod(null)argsnull होने के कारण, एक शून्य तत्व के साथ सरणी के बजाय क्यों?

+0

अब जब आप उत्तर जानते हैं, तो आप इस पहेली पर काम कर सकते हैं। आपके पास दो विधियां हैं, 'शून्य एम (ऑब्जेक्ट) {} 'और' शून्य एम (पैराम्स ऑब्जेक्ट []) {} '। आप 'एम (शून्य) 'कहते हैं।कौन सा अधिभार चुना जाता है, इसे क्या पास किया जाता है, और क्यों? –

+2

मुझे इससे पहले सामना करना पड़ा है। मुझे लगता है कि सिर्फ एक विधियों का नाम बदल दिया गया है। :) – FishBasketGordo

उत्तर

29

params पैरामीटर केवल मान निर्दिष्ट करने का एक सुविधाजनक तरीका प्रदान करने के लिए है - आप अभी भी एक सरणी संदर्भ सीधे पास कर सकते हैं।

अब, null या तो string[] या string के लिए परिवर्तनीय है, इसलिए दोनों व्याख्याओं मान्य हैं - यह कल्पना जो पसंद किया जाता है पर निर्भर है। अनुभाग में कल्पना राज्यों 10.6.1.4 कि:

  • तर्क एक पैरामीटर सरणी के लिए दिया एक भी अभिव्यक्ति है कि परोक्ष पैरामीटर सरणी प्रकार के लिए परिवर्तनीय है हो सकता है। इस मामले में, पैरामीटर सरणी एक मान पैरामीटर की तरह कार्य करता है।

  • वैकल्पिक रूप से, [...]

दूसरे शब्दों में, संकलक चेकों को देखने के लिए कि क्या तर्क पहले "सामान्य" पैरामीटर प्रकार के रूप में मान्य है, और केवल एक सरणी अगर बनाता है यह बिल्कुल है।

+4

इसके अलावा, यह ध्यान देने योग्य है कि पैरामीटर सरणी लेने वाली कई विधियों में ऑब्जेक्ट (ऑब्जेक्ट), (ऑब्जेक्ट, ऑब्जेक्ट) और (ऑब्जेक्ट, ऑब्जेक्ट, ऑब्जेक्ट) के लिए ओवरलोड भी होंगे - यह एक सरणी बनाने के ओवरहेड से बचने के लिए है केवल कुछ ऑब्जेक्ट्स के लिए ऑब्जेक्ट करें, क्योंकि इन अधिभारों का मिलान पहले किया जाएगा। –

3

इसका कारण यह है कि आप उपयुक्त प्रकार की सरणी params तर्क में पास कर सकते हैं। चूंकि null किसी भी प्रकार में परिवर्तित किया जा सकता है, और सरणी वाक्यविन्यास को प्राथमिकता दी जाती है, तो आपको अपने पैरामीटर के मान के रूप में null मिलता है।

जाहिर है इसे string पर कास्टिंग, यह सरणी के बजाय सरणी का तत्व बन जाता है।

आप इसे कोशिश करते हैं और देख सकते हैं:

private void DoSomething(params IEnumerable[] arr) { 
    // ... 
} 

... 

DoSomething(new IEnumerable[] {new int[] {}}); // arr[0] isn't IEnumerable[], it's int[]. 

And here's an online demo.

3

आप एक पैरामीटर पैरामीटर के लिए एक सरणी पारित कर सकते हैं - वास्तव में, यह बेहतर है (Ie अगर आप एक के लिए एक वस्तु [] पारित विधि जो पैराम ऑब्जेक्ट लेती है [], यह संपूर्ण पैरामीटर है, केवल एक तत्व नहीं)। नल एक सरणी के लिए एक असाइनमेंट के रूप में मान्य है, तो - बाध्यकारी जीत।

असल में, आप अधिक स्पष्ट होने के लिए तैयार होंगे।

7

सी # विनिर्देश, अनुभाग 10.6.1 देखें।4 पैरामीटर सरणियों:

एक पैरामीटर सरणी तर्क परमिट एक विधि मंगलाचरण में दो तरीकों में से एक में निर्दिष्ट किया जा करने के लिए:

  • तर्क एक पैरामीटर सरणी के लिए दिया एक भी अभिव्यक्ति परोक्ष है कि हो सकता है परिवर्तनीय (§6.1) पैरामीटर सरणी प्रकार के लिए। इस मामले में, पैरामीटर सरणी एक मान पैरामीटर की तरह कार्य करता है।
  • वैकल्पिक रूप से, आमंत्रण पैरामीटर सरणी के लिए शून्य या अधिक तर्क निर्दिष्ट कर सकता है, जहां प्रत्येक तर्क एक अभिव्यक्ति है जो पैरामीटर सरणी के तत्व प्रकार के लिए पूर्ण रूप से परिवर्तनीय (§6.1) है। इस मामले में, आमंत्रण पैरामीटर सरणी प्रकार का उदाहरण बनाता है जिसमें तर्कों की संख्या से संबंधित लंबाई होती है, दिए गए तर्क मानों के साथ सरणी उदाहरण के तत्वों को प्रारंभ करता है, और वास्तविक तर्क के रूप में नव निर्मित सरणी उदाहरण का उपयोग करता है।

null के बाद से परोक्ष string[] के लिए परिवर्तनीय यह सरणी के रूप में इस्तेमाल किया जाएगा,।

इसके अलावा

:

जब अधिभार संकल्प प्रदर्शन, एक पैरामीटर सरणी के साथ एक विधि या तो अपने सामान्य रूप में या अपने विस्तारित रूप में लागू हो सकता है (§7.5.3.1)। विधि का विस्तारित रूप केवल तभी उपलब्ध होता है जब विधि का सामान्य रूप लागू न हो और केवल तभी विस्तारित रूप के समान हस्ताक्षर वाला विधि पहले से ही उसी प्रकार में घोषित नहीं किया गया हो।

जो स्पष्ट करता है कि संकलक वास्तव में पहले से पहले यह एक सरणी तत्व (विस्तृत रूप) के रूप में तर्क का उपयोग की कोशिश करता है एक सरणी तर्क (सामान्य रूप) के साथ विधि का उपयोग करने की कोशिश करता है।

2

भाषा विनिर्देश से:

  • तर्क एक पैरामीटर सरणी के लिए दिए गए एक हो सकता है:

    एक पैरामीटर सरणी तर्क एक विधि मंगलाचरण में दो तरीकों में से एक में निर्दिष्ट किया जा करने के लिए परमिट एकल अभिव्यक्ति जो पैरामीटर सरणी प्रकार में पूर्ण रूप से परिवर्तनीय (§6.1) है। इस मामले में, पैरामीटर सरणी एक मान पैरामीटर की तरह कार्य करता है।

  • वैकल्पिक रूप से, आमंत्रण पैरामीटर सरणी के लिए शून्य या अधिक तर्क निर्दिष्ट कर सकता है, जहां प्रत्येक तर्क एक अभिव्यक्ति है जो पैरामीटर सरणी के तत्व प्रकार के लिए पूर्ण रूप से परिवर्तनीय (§6.1) है। इस मामले में, आमंत्रण पैरामीटर सरणी प्रकार का उदाहरण बनाता है जिसमें तर्कों की संख्या से संबंधित लंबाई होती है, दिए गए तर्क मानों के साथ सरणी उदाहरण के तत्वों को प्रारंभ करता है, और वास्तविक तर्क के रूप में नव निर्मित सरणी उदाहरण का उपयोग करता है।

के बाद से ParamsMethod(null) में null परोक्ष (string[])null में बदला जा सकता, पहला नियम है कि लागू किया जाता है।

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