अद्यतन: This question was the subject of my blog on June 25th, 2012। महान सवाल के लिए धन्यवाद!
Linq के साथ, सीमा चर परोक्ष संग्रह से आ रही है से टाइप किया जा सकता है, लेकिन एक foreach बयान var कीवर्ड के बिना एक ही बात नहीं कर सकते।
यह सही है।
यह क्यों है?
मुझे कभी नहीं पता कि "क्यों" प्रश्नों का उत्तर देना है। तो मैं आपको एक अलग प्रश्न पूछने का नाटक करूंगा:
दो अलग-अलग तरीके हैं जिन्हें एक नामित चर को स्पष्ट रूप से टाइप किया जा सकता है। एक नामित स्थानीय चर, लूप वैरिएबल, फोरैच लूप वेरिएबल, या कथन वैरिएबल का उपयोग करके स्पष्ट रूप से "var" को इसके स्पष्ट प्रकार के लिए प्रतिस्थापित करके टाइप किया जा सकता है। एक लैम्ब्डा पैरामीटर या क्वेरी रेंज वैरिएबल को पूरी तरह से अपने प्रकार को छोड़कर टाइप किया जा सकता है।
सही।
यह एक असंगतता है। एक बुनियादी डिजाइन सिद्धांत यह है कि असंगतता से बचा जाना चाहिए क्योंकि यह भ्रमित है; उपयोगकर्ता स्वाभाविक रूप से मानता है कि एक असंगतता अर्थ व्यक्त करती है। क्या इन सुविधाओं को लगातार बनाया जा सकता है?
दरअसल, दो तरीके हैं जो वे लगातार बना सकते थे।
Func<double, double> f = (var x)=>Math.Sin(x);
var query = from var customer in customers
join var order in orders on customer.Id equals ...
सभी डिजाइन समझौते की एक श्रृंखला है: पहला, ताकि आप कह सकते हैं कि "var" की आवश्यकता के लिए हर जगह, है। यह स्थिरता परीक्षण को पूरा करता है लेकिन अब घबराहट और verbose लगता है।
x = 12; // Same as "int x = 12;"
using(file = ...) ...
for(i = 0; i < 10; ++i) ...
foreach(c in customers) ...
पहले तीन मामलों में हम अब अनजाने की "परोक्ष घोषित स्थानीय लोगों" सुविधा के बजाय "परोक्ष टाइप किया जोड़ लिया है:
दूसरा ताकि आप कह सकते हैं कि" var "को खत्म करने के लिए हर जगह, है स्थानीय लोगों "। ऐसा लगता है कि एक नया स्थानीय चर घोषित करने के लिए अजीब और गैर-सी # जैसा लगता है क्योंकि आपने किसी ऐसे नाम को असाइन किया था जिसका पहले उपयोग नहीं किया गया था। यह ऐसी सुविधा है जिसे हम जेस्क्रिप्ट या वीबीस्क्रिप्ट जैसी भाषा में उम्मीद करेंगे, सी # नहीं।
हालांकि, foreach ब्लॉक में यह संदर्भ से स्पष्ट है कि एक स्थानीय चर पेश किया जा रहा है। हम बहुत अधिक भ्रम पैदा किए बिना यहां "var" को खत्म कर सकते हैं, क्योंकि "इन" को असाइनमेंट के लिए गलत नहीं माना जाता है।
ठीक है, तो चलो हमारे संभव सुविधाओं योग करते हैं:
- फ़ीचर 1: हर जगह वर की आवश्यकता है।
- फ़ीचर 2: कहीं भी var की आवश्यकता नहीं है।
- फ़ीचर 3: लूप और usings के लिए, स्थानीय लोगों पर वर की आवश्यकता नहीं है, लेकिन छोरों, lambdas या सीमा चर
- सुविधा 4 foreach: का उपयोग करने और foreach, लेकिन नहीं lambdas या सीमा चर छोरों के लिए स्थानीय लोगों पर वर की आवश्यकता होती है,
पहले दो में स्थिरता के लाभ हैं, लेकिन स्थिरता केवल एक कारक है। पहला एक गुंजाइश है। दूसरा एक बहुत गतिशील और भ्रमित है। तीसरे और चौथे लोग व्यावहारिक समझौते की तरह लगते हैं, हालांकि वे लगातार नहीं हैं।
सवाल तो यह है: foreach पाश चर अधिक एक स्थानीय चर या अधिक एक लैम्ब्डा पैरामीटर की तरह की तरह है? स्पष्ट रूप से यह एक स्थानीय चर की तरह है; वास्तव में, foreach loop निर्दिष्ट एक पुनर्लेखन के रूप में है जिसमें लूप चर एक स्थानीय चर बन जाता है।"फॉर" लूप के साथ स्थिरता के लिए, और फोरैच लूप के सी # 1.0 और सी # 2.0 उपयोग के साथ स्थिरता के लिए, जिसे किसी प्रकार का एक प्रकार की आवश्यकता होती है, हम विकल्प चार को विकल्प तीन से बेहतर चुनते हैं।
मुझे आशा है कि आपके प्रश्न का उत्तर दें। यदि नहीं, तो एक बहुत अधिक विशिष्ट सवाल पूछें।
मुझे विश्वास नहीं है कि ex1 सही है - यह संकलित नहीं होगा। क्या आपका मतलब कर्मचारी नहीं है [] emps = new [] {नया कर्मचारी (...)}; ... और आपके दूसरे उदाहरण में ... foreach को टी में टी को डालने में कोई समस्या नहीं होनी चाहिए [] या किसी भी IENumerable ... इसलिए मुझे यकीन नहीं है कि मैं उस समस्या को समझता हूं जिसका आप वर्णन कर रहे हैं। –
Jeff
क्षमा करें पहले यहां पोस्ट करें ताकि साइट कैसे काम करती है। हाँ दूसरा dexample पहले से संबंधित होने का इरादा नहीं है मेरे बुरे को केवल linq परिणाम के बजाय सरणी में सरणी डाल दिया जाना चाहिए था। – mgmedick
मैंने इसे इंगित करने के लिए अपना कोड अपडेट किया है, और मेरा उत्तर :) –