2009-09-26 14 views
8

तो, कई बार हमारे पास ऐसा फ़ंक्शन होता है जो पैरामीटर के रूप में एक आईनेमेरेबल या आईसीओलेक्शन स्वीकार करता है। ,IENumerable <T> या ICollection <T> बनाने के लिए सबसे आसान और सबसे कॉम्पैक्ट तरीका क्या है?

T o1, o2, o3; 
Foo(new T[] { o1, o2, o3 }); 

मैं हमेशा किसी सरणी या एक सूची बनाई है की तरह मैं: ऐसे मामलों में जहां हम एक आइटम नहीं हैं, लेकिन कोई संग्रह उन्हें पकड़ करने के लिए हमें की तरह कार्य करने के लिए उन्हें गुजर, इससे पहले कि एक संग्रह बनाना चाहिए पिछले उदाहरण में किया है। लेकिन मुझे आश्चर्य है, क्या आवश्यक IENumerable या ICollection बनाने के लिए एक और शानदार तरीका है?

यह काफी शांत हो सकता है अगर एक ऐसा कर सकता है:

Foo({ o1, o2, o3 }); 

और संकलक सबसे अमूर्त संभव संग्रह है कि IEnumerable या ICollection की जरूरतों को पूरा करेगे (पर समारोह को स्वीकार करता है जो एक आधार)।

किसी भी तरह, आप एक IENumerable या ICollection पैरामीटर के लिए ओ 1, ओ 2 और ओ 3 कैसे पारित करेंगे?

उत्तर

10

सी # (3) के वर्तमान संस्करण एक अंकन स्पष्ट प्रकार के बिना,

Foo(new [] { o1, o2, o3 }) 
का समर्थन करता है यानी एक सरणी बनाने के लिए

। संख्याओं की निरंतर श्रृंखला बनाने के लिए लिंक के Enumerable.Range भी हैं। बाकी सब कुछ लागू किया जाना है। जावा की भावना में:

public static IEnumerable<T> AsList<T>(params T[] values) { 
    return values; 
} 

इस तरह के नाम से जाना:

Foo(Enumerable.AsList(o1, o2, o3)); 
+1

मेरा सुझाव है कि 'AsList()' नहीं एक अच्छा नाम एक तरीका है जिसके एक 'Enumerable', नहीं' List' रिटर्न के लिए है! 'एन्यूमेरेबल.क्रेट 'के बारे में कैसे? –

2

फू मान लिया जाये कि उम्मीद है एक IEnumerable < टी >, आप प्रकार निष्कर्ष का लाभ उठाने और कर सकते हैं:

T o1, o2, o3; 
Foo(new []{o1, o2, o3}); 
3

कभी कभी मैं एक "पैरामीटर" तर्क के साथ एक पद्धति का उपयोग किया।

Foo(params T[] ts) 

और यदि मैं आईनेमरेबल पर मृत सेट हूं, तो बस उस विधि को उस व्यक्ति को प्रतिनिधि दें जो IENumerable चाहता है।

Foo(params T[] ts) { Foo(ts.AsEnumerable()); } 

आपको असीमित कॉल करना होगा या आप रिकर्स करने जा रहे हैं।

2

एक सरणी बनाना और गुजरना शायद सी # के वर्तमान संस्करण में इसे पूरा करने का सबसे सरल/सबसे शानदार तरीका है। आप अंतर्निहित सरणी टाइपिंग का लाभ (यानी new[] { ... } ले जा सकते हैं, लेकिन यह है कि जहाँ तक यह जाता है

मुझे लगता है कि आप वास्तव में इस एफ # वाक्य रचना की सी # बराबर की तलाश कर रहे:।

let foo = seq [ o1; o2; o3 ] 

जो एक उत्पन्न करता है IEnumerable<T> जो निर्दिष्ट तत्वों पर पुन: सक्रिय होगा। ('सेक' वास्तव में 'आईन्यूमेरेबल' के लिए एफ # उपनाम है, हालांकि एफ # में उनके लिए अंतर्निहित समर्थन है।)

दुर्भाग्यवश, चूंकि यह काफी हद तक कार्यात्मक धारणा है, वहां है कोई सी # समतुल्य नहीं है - हालांकि कौन जानता है कि इसे कब जोड़ा जाएगा, क्योंकि सी # अधिक से अधिक मजेदार हो जाता है ctional।

0

यदि आपके पास कोई ऐसा तरीका है जो अपने अंतिम पैरामीटर के रूप में एक सरणी लेता है, तो यह पैरामीटर params को चिह्नित करने के लिए समझ में आता है।

Foo(o1, o2, o3); 

मैं क्योंकि अक्सर एक इकाई में परीक्षण मेरी मापदंडों के बजाय एक सरणी में, इस तरह अलग कर रहे हैं जब Foo() के लिए एक इकाई परीक्षण लिखने के इस विशेष रूप से उपयोगी,: यह आप इस तरह विधि कॉल करने देता है।

अगर Foo() का अधिभार होता है तो मैं ऐसा करने के खिलाफ सलाह देता हूं जो उस स्थिति में कोई सरणी नहीं लेता है, क्योंकि यह जल्दी से भ्रमित हो सकता है।

काश है कि सी # भाषा IList<T> के लिए अनुमति दी params:

void Foo(params IList<T> ts) { ... } 
संबंधित मुद्दे