C # में "इनलाइन" ऐरे का उपयोग नहीं कर सकते?


92

कल्पना कीजिए कि आपके पास यह कहीं है

public static T AnyOne<T>(this T[] ra) where T:class
    {
    int k = ra.Length;
    int r = Random.Range(0,k);
    return ra[r];
    }

या सिर्फ यह भी

public static string OneOf(this string[] strings)
    {
    return "a";
    }

फिर, बेशक आप यह कर सकते हैं ...

string[] st = {"a","b","c"};
string letter = st.AnyOne();

... जो माहान है। परंतु। ऐसा प्रतीत होता है कि आप ऐसा नहीं कर सकते:

string letter = {"a","b","c"}.AnyOne();

या वास्तव में शायद यह

string letter = ( {"a","b","c"} ).AnyOne();

या कुछ और मैंने कोशिश की।

वास्तव में (1) कोई ऐसा क्यों नहीं कर सकता है? और (2) क्या मुझे कुछ याद आ रहा है, अगर कोई रास्ता है तो आप कैसे करेंगे?


5
मुझे यकीन नहीं है कि डुप्लिकेट प्रश्न उपयुक्त है, ओपी आरंभी इनिशियलाइज़र्स के बारे में नहीं पूछ रहा है, लेकिन कंपाइलर ऑब्जेक्ट को सरणी के रूप में पहचान नहीं करेगा, जब तक कि इसे असाइन नहीं किया जाता है।
— रॉन बेयर

4
मैं C # शब्दावली से परिचित नहीं हूं, लेकिन मेरा मानना ​​है कि यह एक इनलाइन के बजाय सामान्यतः एक शाब्दिक या एक सरणी शाब्दिक कहा जाता है ।
— चि

3
वह वाक्य-विन्यास तत्व एक सरणी आरंभीकरण या संग्रह आरंभीकरण है , इस संदर्भ के आधार पर जिसमें इसका उपयोग किया जाता है। न तो मामले में इसे एक अभिव्यक्ति के रूप में वर्गीकृत किया गया है ।
— एरिक लिपर्ट

जवाबों:


132

आपको पहले सरणी का उपयोग करना होगा new[]।

string letter = (new[] {"a","b","c"}).AnyOne();

जैसा कि @hvd ने उल्लेख किया है कि आप इसे परांठे के बिना कर सकते हैं (..), मैंने परांठे को जोड़ा क्योंकि मुझे लगता है कि यह अधिक पठनीय है।

string letter = new[] {"a","b","c"}.AnyOne();

और आप डेटा प्रकार निर्दिष्ट कर सकते हैं new string[]जैसा कि अन्य उत्तरों में उल्लेख किया गया है।


आप बस नहीं कर सकते {"a","b","c"}, क्योंकि आप इसे सरणी को आबाद करने के तरीके के रूप में सोच सकते हैं, इसे बनाने के लिए नहीं।

एक और कारण यह होगा कि कंपाइलर भ्रमित हो जाएगा, पता नहीं क्या बनाएगा, उदाहरण के लिए, string[]{ .. }या एक List<string>{ .. }।

सिर्फ new[]कंपाइलर का उपयोग करके डेटा प्रकार ( ".."), के बीच {..}, आप जो चाहते हैं ( string) जान सकते हैं । आवश्यक हिस्सा है [], इसका मतलब है कि आप एक सरणी चाहते हैं।

आप एक खाली सरणी भी नहीं बना सकते new[]।

string[] array = new []{ }; // Error: No best type found for implicity-typed array

13
आपको उन कोष्ठकों की आवश्यकता नहीं है। string letter = new[] {"a","b","c"}.AnyOne();बस ठीक है। यदि आप उन्हें चाहते हैं, यदि आपको लगता है कि यह कोष्ठक के साथ अधिक पठनीय है, तो वे मान्य हैं, लेकिन उस मामले में मुझे लगता है कि यह कम से कम यह उल्लेख के लायक है कि यह आपके पक्ष में एक सचेत विकल्प है, कि यह भाषा द्वारा मजबूर नहीं किया गया था।

मैं वाक्यविन्यास नए [] {1,2} के बारे में जानता हूं, लेकिन क्या एक भी सरल वाक्यविन्यास है? [१, २] जैसा कुछ?
— सेगूसो

51

(१) कोई ऐसा क्यों नहीं कर सकता? {"a","b","c"}.AnyOne();

यह रेखा:

string[] st = {"a","b","c"};

समकक्ष सरणी निर्माण अभिव्यक्ति के लिए एक छोटा हाथ है ( ILSpy के तहत )

string[] st = new string[]  {"a","b","c"};

यह string[] st = {"a","b","c"} केवल घोषणा के समय उपयोग किया जा सकता है , आप इसे कहीं और उपयोग नहीं कर सकते, आप भी नहीं कर सकते हैं:

string[] st;
st = {"a", "b", "c"}; //Error

सी # भाषा विनिर्देशों में ऐरे क्रिएशन एक्सप्रेशन के लिए इसे खंड 7.6.10.4 के तहत समझाया गया है ।

तो यह "{"a", "b", "c"}"घोषणा में उपयोग के बिना अकेले कुछ भी नहीं है। इसलिए आप इसे अपनी एक्सटेंशन विधि के साथ उपयोग नहीं कर सकते, क्योंकि आपकी एक्सटेंशन विधि किसी सरणी पर काम करती है।

(२) क्या मुझे कुछ याद आ रहा है, अगर कोई रास्ता है तो आप कैसे करेंगे?

पहले से ही @ adricadar के उत्तर में उल्लिखित है , आप कर सकते हैं:

(new[] {"a","b","c"}).AnyOne();

या

(new string[] {"a","b","c"}).AnyOne();

48

मैं "क्यों नहीं" सवाल पर वापस धक्का क्योंकि पहले, जवाब लगभग संतोषजनक नहीं हैं - आप पहले से ही जवाब मिल गया है "सुविधा वह तरीका नहीं है जो आप इसे चाहते हैं क्योंकि विनिर्देश यह नहीं कहता कि आप क्या कहना चाहते हैं" , जो मुझे लगता है कि एक विशेष रूप से संतोषजनक जवाब नहीं था। दूसरा, डिजाइन टीम को यह बताने का औचित्य नहीं है कि दुनिया वैसी नहीं है जैसा आप चाहते हैं; सुविधाएँ मुफ्त में मौजूद नहीं हैं और फिर उन्हें भाषा से डिज़ाइन किया गया है; इसके बजाय, सुविधाओं को पहले उचित ठहराया जाना चाहिए, और फिर डिज़ाइन किया जाना चाहिए।

तो चलिए आपका "क्यों नहीं" बनाने की कोशिश करते हैं थोड़ा और कुरकुरा सवाल। मौजूदा विशेषता यह है कि "एक सरणी इनिशलाइज़र का उपयोग (a) एक प्रकार के ऑब्जेक्ट कंस्ट्रक्शन के दाईं ओर इनिशियलाइज़ेशन या (b) में समतलों के दाईं ओर किया जा सकता है।" प्रस्तावित विशेषता यह है: "एक सरणी आरंभीकरण का उपयोग एक अभिव्यक्ति के रूप में भी किया जा सकता है"। सवाल यह है कि क्या एरिक प्रस्तावित सुविधा की आलोचना करेंगे?

मेरी पहली आलोचना यह होगी कि यह स्पष्ट नहीं है कि अभिव्यक्ति का प्रकार क्या है। एक वैरिएबल इनिशियलाइज़र में आपके पास वैरिएबल का प्रकार होता है और ऑब्जेक्ट क्रिएशन एक्सप्रेशन में आपके पास ऑब्जेक्ट का प्रकार होता है; इन दोनों से हम निर्मित सरणी के प्रकार को घटा सकते हैं। या तो संकेत के बिना, हमें किस प्रकार की कटौती करनी चाहिए?

C # 1.0 में, जब इस सुविधा को जोड़ा गया था, तो भाषा में बनाए गए कुल प्रकार के शून्य प्रकार के भव्य थे। C # के शुरुआती दिनों में एक डिजाइन सिद्धांत "कोई आश्चर्य नहीं" था, और यह कि कंपाइलर "बहुत स्मार्ट" नहीं था। यदि डेवलपर किसी विशेष प्रकार का होना चाहता है, तो वह अभिव्यक्ति में किसी प्रकार स्पष्ट होना चाहिए। जब आप कहें

new double[] { 1, 2, 3.4 }

यह बहुत स्पष्ट है कि किस प्रकार का इरादा है। उसी प्रकार

new Animal[] { cat, dog, null }

प्रस्तावित विशेषता इस सिद्धांत का उल्लंघन करती है। अभिव्यक्ति का एक प्रकार होना चाहिए, लेकिन यह किसी भी तरह से स्पष्ट नहीं है कि तर्क किस प्रकार का है

M({cat, dog, null})

इसके अलावा: मान लीजिए कि हमारे पास दो ओवरलोड हैं M, जिनमें से एक का एक सरणी लेता है Animalऔर एक का एक सरणी लेता है IPet। कौन सा अधिभार Mलागू है? क्या रूपांतरणों में से एक दूसरे से बेहतर है? तत्वों के प्रकार हैं Catऔर Dog; क्या यह एक प्रकार को कम करने के लिए समझ में आता है जो वहां भी दिखाई नहीं देता है? ये सभी प्रश्न हैं जिन्हें डिजाइन टीम द्वारा विचार किया जाना चाहिए, और ये ऐसे प्रश्न हैं जिनके स्पष्ट उत्तर नहीं हैं। प्रस्तावित विशेषता हमें काफी कम क्रम में गहरे पानी में ले जाती है।

अब, C # 3.0 इस समस्या का हल करता है क्योंकि C # 3.0 में कई विशेषताएं जोड़ी गई हैं जहाँ कंपाइलर डेवलपर की ओर से टाइप करता है। "कोई आश्चर्य नहीं" और "सरल नियम" के बारे में पहले के सिद्धांत लिनक्यू काम करने के लिए आवश्यक अन्य डिजाइन सिद्धांतों के साथ संघर्ष में थे। क्या आपके द्वारा प्रस्तावित फीचर को C # 3.0 में जोड़ा जाना चाहिए?

यह भी हो सकता है। यह सुविधा वास्तव में C # 3.0 में जोड़ी गई थी:

new[] { x, y, z }

एल्गोरिथ्म का उपयोग करके सरणी के प्रकार को संक्रमित करता है: टाइप करने वाले तत्वों के लिए अभिव्यक्तियाँ लें, यह निर्धारित करें कि उन प्रकारों में से कौन सा सबसे सामान्य प्रकार है, जिसके लिए अन्य सभी अभिव्यक्तियाँ परिवर्तनीय हैं, और यदि ऐसा कोई प्रकार मौजूद है, तो उसे चुनें। अन्यथा एक त्रुटि का उत्पादन,

new[]वैकल्पिक बनाने के लिए उस सुविधा को और शिथिल किया जा सकता था । ऐसा नहीं किया गया।

अब, यदि आपने मुझे प्रस्तावित सुविधा की आलोचना करने के लिए C # 3.0 समय-सीमा में मुझसे पूछा था, तो मैंने बताया है कि (1) C # 3.0 संकलक पहले से ही पूरी रिलीज़ के लिए शेड्यूल को खिसकाने के गंभीर खतरे में था, इसलिए हम इसे और न जोड़ें डिजाइन, कार्यान्वयन और परीक्षण के बोझ को पूरी तरह से अनावश्यक सुविधा के लिए जो उपयोगकर्ता को छह कीस्ट्रोक्स बचाता है , और (2) C # 3.0 ने संग्रह संग्रहकर्ताओं को भी जोड़ा:

new List<int>() { 10, 20, 30 }

{10, 20, 30}स्वचालित रूप से एक सरणी क्यों होनी चाहिए ? ऐसा क्यों नहीं होना चाहिए List<int>? या कई अन्य प्रकारों में से कोई एक? सरणियों के प्रति पूर्वाग्रह क्यों? याद रखें, एक बार जब हम सरणियों के लिए वाक्यविन्यास को सुनिश्चित करना चुनते हैं, तो हम हमेशा के लिए इसके साथ फंस जाते हैं । यह कभी भी कुछ और नहीं हो सकता है, इसलिए प्रस्तावित सुविधा न केवल अनावश्यक है, यह भविष्य की संभावित सुविधाओं को भी रोकता है जो प्रशंसनीय लगती हैं।

सारांश: प्रस्तावित सुविधा ने C # 1.0 के कुछ डिज़ाइन सिद्धांतों का सीधे उल्लंघन किया। यह C # 3.0 में अनावश्यक बोझ के अलावा और कुछ नहीं जोड़ता है। C # 3.0 के बाद से भाषा के सभी संस्करणों में, प्रस्तावित सुविधा में कई अन्य योग्य सुविधाओं पर समय, प्रयास और धन खर्च करने की सिफारिश करने के लिए कोई अच्छा तर्क नहीं है।

इसलिए, ऐसी कोई सुविधा नहीं है।


हे, आपको एक टी-शर्ट मुद्रित करने की आवश्यकता है "दुनिया जिस तरह से आप चाहते हैं कि वह" उस पर छपी नहीं है :)
— slugster

6
@JoeBlow: सबसे पहले, आपका बहुत स्वागत है। "क्यों नहीं" के बारे में - आपकी टिप्पणी समस्या को अच्छी तरह से दर्शाती है। जब कुछ लोग "क्यों" सवाल पूछते हैं तो वे तार्किक औचित्य की तलाश में हैं । कुछ लोग व्यावहारिक औचित्य की तलाश में हैं । और आप स्पष्ट रूप से नियम का वर्णन करने वाली विनिर्देश की लाइन की तलाश कर रहे हैं । यह इतना अस्पष्ट है कि एक अच्छा जवाब देना मुश्किल है जो प्रश्नकर्ता के दिमाग में वास्तव में प्रश्न को लक्षित करता है। "क्यों नहीं" प्रश्न और भी बुरे हैं क्योंकि वे उन चीजों के बारे में अस्पष्ट प्रश्न हैं जो मौजूद नहीं हैं ।
— एरिक लिपर्ट

3
@EricLippert यह उन चीजों के बारे में सवाल से भी बदतर है जो _might_ मौजूद हैं : यदि आप किसी टीम के साथ सॉफ़्टवेयर पर काम कर रहे हैं, तो पूरी टीम सुविधाओं के बारे में सोचने और परिणामों को संतुलित करने के लिए हर साल खर्च करती है। निर्णय लिए जाते हैं। फ़ीचर अनुरोध और 'क्यों' औचित्य के लिए पूछता है। हालांकि, इसका मतलब यह नहीं है कि कोई व्यक्ति बस कुछ करना चाहता है, जो मूल रूप से टीम के निर्णय पर ही सवाल उठाता है। इससे भी बदतर, यह सवाल पूछने वाला व्यक्ति आमतौर पर विषय के बारे में बहुत कम जानता है। जैसे, मुझे लगता है कि सवाल को पूरी तरह से निष्पक्ष क्यों नहीं बताया गया है। अच्छी नौकरी आई.एम.ओ.
— 15'15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.