2013-02-10 7 views
6

मैं कुछ अलग-अलग प्रकार के सरणी (उदाहरण के लिए double[], float[], int[]) के साथ एक छोटी परियोजना पर काम कर रहा हूं। सत्यापन/परीक्षण/स्वच्छता उद्देश्यों के लिए, मैं इन सरणी में से कुछ को कंसोल पर प्रिंट कर रहा हूं क्योंकि मैं साथ जाता हूं। इसलिए मैं कई कार्यों कि नीचे इन की तरह लग रही है (इस उदाहरण के लिए सरल बनाया - मान मैं केवल एकल आयाम सरणियों के साथ काम कर रहा हूँ):सिस्टम क्यों नहीं हो सकता है। ऐरे एक प्रकार की बाधा बनें?

void Print(float[] a) // prints an array of floats 
{ 
    for (int i = 0; i < a.Length; i++) 
    { 
     Console.Write(a[i]); 
    } 
} 

void Print(double[] a) // prints an array of doubles 
{ 
    for (int i = 0; i < a.Length; i++) 
    { 
     Console.Write(a[i]); 
    } 
} 

मैं अपने अनंत ज्ञान में, सोचा था कि मैं से कुछ कम हो सकता है इन कार्यों के सामान्य संस्करण को बनाकर कोड डुप्लिकेशन। इसलिए मैंने यह कोशिश की:

void Print<T>(T t) where T : Array 
{ 
    for (int i = 0; i < t.Length; i++) 
    { 
     Console.Write(t.GetValue(i)); 
    } 
} 

Intellisense शिकायत नहीं है, लेकिन संकलक एक बहुत ही दिलचस्प त्रुटि के साथ विफल:

Constraint cannot be special class 'System.Array'

मैं एक विवरण (Object के लिए इसी तरह के लिए देखा या सील वर्गों की है, लेकिन एक के अलावा ज्यादा नहीं मिला है, on msdn का उल्लेख करें। क्या कोई मुझे बता सकता है क्यों यह मामला है? मैं System.Array की एक प्रकार की बाधा निर्दिष्ट क्यों नहीं कर सकता?

पुनश्च: एक ओर जहां यह पूरा लिखने, मुझे एहसास हुआ कि मैं पूरा कर सकते हैं कि क्या मैं मूल रूप से और अधिक आसानी से चाहता था, इस तरह एक साधारण समारोह के साथ:

void Print(System.Array a) 
{ 
    for (int i = 0; i < a.Length; i++) 
    { 
     Console.Write(a.GetValue(i)); 
    } 
} 

इस कारण है कि संकलक में सरणियों के लिए एक विशेष नियम है है ?

void Print<T>(T[] array) 
{ 
    for (int i = 0; i < array.Length; i++) 
    { 
     Console.Write(array[i]); 
    } 
} 

उत्तर

16

आप क्या चाहते करने के लिए उचित वाक्य रचना इस है। यह वही है क्योंकि ValueType बाधा रखने के लिए यह बेकार है, क्योंकि यह वास्तव में यह जांच नहीं करता है कि आप एक सामान्य प्रकार के रूप में एक मान प्रकार का उपयोग करते हैं, लेकिन क्या आप जिस प्रकार से गुज़र रहे हैं वह ValueType पर असाइन किया जा सकता है।
तो आप सामान्य तर्क के रूप में भी Array पास कर सकते हैं और यह ठीक है।

क्या वास्तव में उपयोगी है एक सरणी contraint किसी भी प्रकार कि Array से निकला है की इजाजत दी है, लेकिन नहीं Array ही:

void Print<TArr>(TArr t) where TArr : array //or [*] or other fancy syntax 

कहाँ T[], [,], [,,], [,,,], और इसलिए हो सकता है पर। गैर-जेनेरिक Array पैरामीटर का एकमात्र ओवर यह है कि हम सरणी के तत्व प्रकार को जानते हैं।

इस हल करने के लिए एक और तरीका है T[] की अंतर्निहित ऑपरेटर भार के, T[,], के साथ एक कस्टम Array<T> वर्ग बनाने के लिए है T[,,] आदि

संपादित करें:
सीआईएल (वर्तमान में) में भी इस लक्ष्य को हासिल करने के लिए कोई तरीका नहीं है, क्योंकि int[,] और Array किसी भी इंटरफेस या कन्स्ट्रक्टर में भिन्न नहीं हैं। हमें where T : Array but not Array itself संयम की आवश्यकता है।

+1

समझ में आता है, लेकिन मैं अभी भी उत्सुक हूं _why_ मेरे पास 'ऐरे' की बेस क्लास प्रकार की बाधा नहीं हो सकती है ... – vlad

+0

इसके अलावा, जिज्ञासा से, क्या यह 'ऐरे' प्रकार के पैरामीटर का उपयोग करने से अलग है? अगर मैं 'ऐरे' का उपयोग करता हूं तो क्या कुछ मुक्केबाजी चल रही है? – vlad

+1

@vlad कोई मुक्केबाजी नहीं है क्योंकि सरणी संदर्भ प्रकार हैं, मूल्य प्रकार नहीं, हालांकि आप बॉक्सिंग कर रहे हैं जो आप टाइप किए गए सरणी के विपरीत इसे प्राप्त करते हैं। यह भी वही नहीं है क्योंकि 'ऐरे' 2, 3, या एन dimentional सरणी, या एक सरणी भी हो सकती है जो 0 अनुक्रमित नहीं है। – Servy

1

तो सवाल सचमुच लिया, यह एक Array बाधा है करने के लिए बेकार हो सकता है:

+0

यह काफी बेकार नहीं होगा। क्या यह निषेध के लिए नहीं था, कोई एक 'CopyAndReverseArraySegment (टी dest, टी स्रोत, int start, int length) लिख सकता है जहां टी: System.Array' और यह उन आमंत्रणों को स्वीकार करता है जहां या तो दोनों या स्रोत या गंतव्य ' System.Array', लेकिन अभी भी उन आमंत्रणों को अस्वीकार करें जहां 'स्रोत' और 'dest' असंगत सरणी प्रकार थे। जैसा कि है, मुझे विश्वास नहीं है कि 'System.Array' को उस प्रकार के व्युत्पन्न किए बिना पैरामीटर में से किसी एक के लिए किसी विशेष प्रकार के रूप में अनुमति देने का एक तरीका भी स्वीकार्य माना जाता है। – supercat

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