2013-01-05 46 views
5

मैं C# AsEnumerable पढ़ रहा हूँ:।।क्यों लागू किया जाना चाहिए अनन्य() एक ऐरे के लिए विधि?

"IEnumerable इंटरफ़ेस एक सामान्य इंटरफ़ेस यह कि प्रकार के पाशन के लिए लागू कर सकते हैं एक टेम्पलेट को परिभाषित करता है इसका मतलब है यह AsEnumerable विधि, एक सामान्य विधि, आप एक कास्ट करने देता है विशिष्ट इसके अलावा पर इसके IEnumerable समकक्ष "

के प्रकार, एक कोड उदाहरण:

using System; 
using System.Linq; 

class Program 
{ 
    static void Main() 
    { 
     // Create an array type. 
     int[] array = new int[2]; 
     array[0] = 5; 
     array[1] = 6; 
     // Call AsEnumerable method. 
     var query = array.AsEnumerable(); 
     foreach (var element in query) 
     { 
      Console.WriteLine(element); 
     } 
    } 
} 

लगता है जैसे मुझे लूपिंग (foreach) का उपयोग करने के लिए एक सरणी को IENumerable टाइप ऑब्जेक्ट में परिवर्तित करने की आवश्यकता है।

लेकिन एक सरणी के लिए सीधे foreach लागू करने पैदावार ठीक उसी परिणाम:

using System; 
//using System.Linq; 

class Program 
{ 
    static void Main() 
    { 
     // Create an array type. 
     int[] array = new int[2]; 
     array[0] = 5; 
     array[1] = 6; 
     // Call AsEnumerable method. 
     //var query = array.AsEnumerable(); 
     foreach (var element in array) 
     { 
      Console.WriteLine(element); 
     } 
    } 
} 

तो, AsEnumerable() विधि का स्पष्टीकरण भी पूरे वेबपेज मेरे लिए शून्य है।
मुझे क्या याद आया?

+3

+1 उदाहरण पूरी तरह से बेवकूफ है, और वेबपृष्ठ के लेखक के पास कोई संकेत नहीं है कि 'AsEnumerable' का उपयोग किस प्रकार किया जाता है। –

+1

मदद के लिए सभी उत्तरदाताओं और विशेष रूप से टिप्पणी करने के लिए धन्यवाद [@ कोनराड रुडॉल्फ] (http://stackoverflow.com/users/1968/konrad-rudolph) मुझे वाक्यविन्यास में रुचि रखने वाले व्यक्ति के साथ भ्रमित होने के लिए परेशानी से दूर रखने के लिए एक विधि उपयोग के।प्रश्न में कुंजी मैं क्या था (लेकिन उद्धृत लेख नहीं, जिसे मैं पूछने से पहले समझ गया) याद किया। मैंने कुछ बार सभी उत्तरों को पढ़ा है, लेकिन मैं वास्तव में बहुत बुद्धिमान और सही सिद्धांतों को पढ़ने के बजाए चलाने के लिए संलग्न कोड चित्रों को पसंद करता हूं। ऐसा लगता है कि सही उत्तर देने के लिए मुझे शिक्षित करने में परेशानी लेने के लिए एक कमी का सामना करना पड़ा है। –

उत्तर

4

उदाहरण खराब है और इसे बुरा महसूस करना चाहिए।

अगर मैं एक विस्तार पद्धति पर परिभाषित किया गया है, मान लें कि,, चलो सरणी प्रकार इस तरह:: यहाँ एक बेहतर, अगर कुछ हद तक काल्पनिक उदाहरण है

public static class ArrayExtension { 

    public static bool Any<T>(this T[] source, Func<T,bool> predicate) 
    { 
     Console.WriteLine("Undesirable side behaviour"); 
     SomeResourceIntensiveOperation(); 

     Console.WriteLine("Inefficient implementation"); 
     return source.Where(predicate).Count() != 0; 
    } 

} 

और मैं

int[] nums = new []{1,2,3,4,5}; 
nums.Any(n=> n % 2 == 0); 
करना

यदि मेरे कार्यान्वयन को निष्पादित और चलाएगा, भले ही मुझे इसकी आवश्यकता न हो।

nums.AsEnumerable().Any(n => n % 2 == 0); 

यह डिफ़ॉल्ट कार्यान्वयन को कॉल करेगा।

वास्तविक लाभ, जब आप IQueryable कार्यान्वयन (जैसे LINQ करने वाली एसक्यूएल) का उपयोग कर रहे है, क्योंकि उदाहरण के लिए, Where for IEnumerable

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source, 
Func<TSource, bool> predicate) 

के रूप में परिभाषित किया गया है लेकिन IQueryable.Where

public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source, 
Expression<Func<TSource, bool>> predicate) 
साथ परिभाषित किया गया है

जब IQueryable व्यवहार अवांछनीय है, तो INumerable व्यवहार को बल देने के लिए AsEnumerable() पर कॉल कर सकते हैं।

+0

क्षमा करें, यह सबसे हास्यास्पद उदाहरण है जिसे मैंने कभी देखा है। उदाहरण के लिए नियम: KISS। यथासंभव सरल। एक बिंदु बनाने के लिए आप बनाते हैं। आपके पास इतने सारे अच्छे स्पष्टीकरण नहीं हैं जो पहले से ही बाहर हो सकते हैं और संदर्भ भी पार नहीं कर सकते हैं - मुझे उम्मीद है कि आप कभी भी प्रोग्रामिंग ट्यूटोरियल कभी नहीं लिखेंगे। – TomTom

+5

@ टॉमटॉम आप अपने घुमावदार से पूरी तरह से बंद होना चाहिए। यह उदाहरण * ASENumerable' के * पूर्ण * चित्रण है। विशेष रूप से, यह एक ** न्यूनतम ** उदाहरण है। इसमें इसके उपयोग को स्पष्ट करने के लिए न्यूनतम सामग्री शामिल नहीं है। मेरा सुझाव है कि आप इस पर एक रात सो सकते हैं, फिर इसे फिर से देखने के लिए वापस आएं। –

+0

@ टॉमटॉम मुझे हमेशा केआईएसएस पर एक भिन्नता पसंद आई: "इसे जितना संभव हो सके उतना आसान रखें, लेकिन आसान नहीं।" :) और मैं वास्तव में नहीं सोचता कि विस्तार विधियों को विस्तारित करते समय जब मैं एक विस्तार विधि की व्याख्या करता हूं तो चीजों को खत्म कर रहा है। – SWeko

1

यह आपके उदाहरण में तार्किक रूप से कोई अर्थ नहीं है (यानी सरणी से)। मुझे लगता है कि पहला कोड शुरुआती द्वारा लिखा गया है, या - अधिक नीचे - एक उदाहरण।

यह LINQ के अर्थ में समझ में आता है कि "AsEnumerable" क्वेरी के मूल्यांकन को ट्रिगर करता है और ओआरएम के आधार पर इसका मतलब लूप के भीतर पुन: उपयोग के लिए डेटाबेस कनेक्शन को मुक्त करना हो सकता है।

यह कहा गया:

आप उदाहरणों में बहुत अधिक पढ़ते हैं। उदाहरण में, कोड "अच्छा" नहीं होना चाहिए बल्कि एक बिंदु दिखाने के लिए है। इस मामले में यह एस्नेमरेबल के उपयोग को हटाने के लिए समझ में आता है - और उदाहरण को छोटा रखने के लिए, एक ऐरे प्रारंभ करने के लिए सबसे तेज़ संख्यात्मक वस्तु (कोड की रेखाओं के संदर्भ में) है। उदाहरण विशिष्ट चीजों को इंगित करते हैं, वे किसी भी चीज़ के लिए "अच्छा कोड" नहीं हैं।

+1

मैं असहमत हूं। जैसे आपने कहा, "एक उदाहरण में, एक बिंदु दिखाने के लिए कोड है ..."। प्रश्न में उदाहरण पूरी तरह से ऐसा करने में विफल रहता है, क्योंकि सरणी में 'AsEnumerable' लगाने में * कोई * बिंदु नहीं है। एक अच्छा उदाहरण इसका उपयोग करने के बीच अंतर और LINQ से SQL क्वेरी में इसका उपयोग नहीं करेगा। क्या आपने वेबसाइट ओपी से जुड़ा है? इसका लेखक पूरी तरह से अनजान है। –

+0

यह एक वाक्यविन्यास बिंदु दृश्य से उपयोग का प्रदर्शन करता है। – TomTom

+1

यह प्रासंगिक या सहायक कैसे है? किसी को भी कुछ सामान्य विधि को कॉल करने के बारे में बताया जाना चाहिए। वे समान रूप से 'foo.Bar() 'को कॉल-अप नामों के साथ कॉल करके समान रूप से प्रदर्शित कर सकते थे,' System.Array' और 'AsEnumerable' का भी उल्लेख करने की आवश्यकता नहीं है। उदाहरण इस से अधिक नहीं दिखाता है। –

2

MSDN

AsEnumerable<TSource> (IEnumerable<TSource>) विधि से अन्य एक प्रकार है कि IEnumerable<T> ही IEnumerable<T> लागू करता है से स्रोत का संकलन समय प्रकार बदलने के लिए की तुलना में कोई प्रभाव नहीं है।

AsEnumerable<TSource> (IEnumerable<TSource>) का उपयोग क्वेरी कार्यान्वयन के बीच चयन करने के लिए किया जा सकता है जब अनुक्रम IEnumerable<T> लागू करता है लेकिन इसमें सार्वजनिक क्वेरी विधियों का एक अलग सेट भी उपलब्ध है। उदाहरण के लिए, एक जेनेरिक क्लास टेबल दिया गया है जो IEnumerable<T> लागू करता है और इसकी अपनी विधियां Where, Select, और SelectMany है, Where पर एक कॉल सार्वजनिक Where तालिका की विधि का आह्वान करेगी। डेटाबेस तालिका का प्रतिनिधित्व करने वाली एक तालिका प्रकार में एक विधि हो सकती है जो भविष्यवाणी तर्क को अभिव्यक्ति वृक्ष के रूप में लेती है और पेड़ को दूरस्थ निष्पादन के लिए SQL में परिवर्तित करती है। यदि रिमोट निष्पादन वांछित नहीं है, उदाहरण के लिए क्योंकि पूर्वानुमान स्थानीय विधि को आमंत्रित करता है, तो AsEnumerable<TSource> विधि का उपयोग कस्टम तरीकों को छिपाने के लिए किया जा सकता है और इसके बजाय मानक क्वेरी ऑपरेटर उपलब्ध करा सकते हैं।

0

यह एक और उदाहरण है। मान लीजिए मैं इस विधि है:

static void MyMeth(int[] numbers) 
{ 
    var query = numbers.Reverse(); // works fine, calls Linq extension 

    // ... use query ... 
} 

तो मैं बजाय एक List<int> में numbers बदलने के लिए, और कोशिश करने का फैसला:

static void MyMeth(List<int> numbers) 
{ 
    var query = numbers.Reverse(); // will not compile! 

    // ... use query ... 
} 

समस्या यहाँ List<> वर्ग एक और विधि है जो भी है है कि Reverse कहा जाता है। वह विधि void लौटाती है (क्योंकि यह मूल List<> इन-प्लेस को संशोधित करती है)। मुझे वह नहीं चाहिए। एक समाधान स्पष्ट numbers Upcast होगा:

static void MyMeth(List<int> numbers) 
{ 
    var query = ((IEnumerable<int>)numbers).Reverse(); // fine; Linq 

    // ... use query ... 
} 

लेकिन एक और समाधान AsEnumerable<> होगा, इसलिए:

static void MyMeth(List<int> numbers) 
{ 
    var query = numbers.AsEnumerable().Reverse(); // fine too; Linq 

    // ... use query ... 
} 

निष्कर्ष:AsEnumerable विधि के प्रयोजन के विशेष पर तरीकों "भूल जाइए" है सामान्य प्रकार IEnumerable<> पर एक्सटेंशन विधियों को "छुपाएं" टाइप करें। यह उस मामले में अविश्वसनीय रूप से महत्वपूर्ण हो सकता है जहां "विशेष" प्रकार IQueryable<> है जहां (एक्सटेंशन) विधियां Where, Select हैं और इसलिए कुछ अलग-अलग करते हैं (अर्थात् लैम्ब्डा को अभिव्यक्ति वृक्ष के रूप में निगलना, इसका विश्लेषण करना और " IEnumerable<> पर Where, Select आदि की तुलना में "इसे एसक्यूएल या कुछ में अनुवाद करें)।