2010-02-25 13 views
18

अब सी # नामित पैरामीटर का समर्थन करता है, मैं यह देखने के लिए जांच कर रहा था कि वीबी ने ऐसा किया था, और पाया कि इसमें थोड़ा अंतर है। इस तरह एक पुस्तकालय समारोह उदाहरण के लिए ले लो:सी # और वीबी हैंडल पैरामीटर नाम के बीच मतभेद?

public static void Foo(string a, string b) 
{ 
    Console.WriteLine(string.Format("a: {0}, b: {1}", a, b)); 
} 

सी # में, यदि आप इसे इस तरह कहते हैं:

Foo(a: "a", b: "b"); 

संकलक निम्नलिखित आईएल निर्देश का उत्पादन:

.locals init (
    [0] string CS$0$0000, 
    [1] string CS$0$0001) 
L_0000: nop 
L_0001: ldstr "a" 
L_0006: stloc.0 
L_0007: ldstr "b" 
L_000c: stloc.1 
L_000d: ldloc.0 
L_000e: ldloc.1 
L_000f: call void [TestLibrary]TestLibrary.Test::Foo(string, string) 
L_0014: nop 
L_0015: ret 

जो निम्नलिखित सी # कोड में अनुवाद करता है:

string CS$0$0000 = "a"; 
string CS$0$0001 = "b"; 
Test.Foo(CS$0$0000, CS$0$0001); 

वीबी में, यदि आप इसे इस तरह कहते हैं:

Foo(a:="a", b:="b") 

संकलक निम्नलिखित आईएल निर्देश का उत्पादन:

L_0000: nop 
L_0001: ldstr "a" 
L_0006: ldstr "b" 
L_000b: call void [TestLibrary]TestLibrary.Test::Foo(string, string) 
L_0010: nop 
L_0011: nop 
L_0012: ret 

निम्नलिखित में से कौन VB कोड के लिए अनुवाद:

Foo("a", "b"); 

जिस तरह से वीबी को बहुत कम निर्देश कॉल की आवश्यकता होती है, तो सी # लागू करने के तरीके के लिए कोई फायदा है? यदि आप नामित पैरामीटर का उपयोग नहीं करते हैं, तो सी # वीबी के समान काम करता है।


संपादित: अब हम निर्धारित किया है कि कि अतिरिक्त निर्देश रिलीज़ मोड में चले जाओ, वहाँ एक विशेष कारण उन्हें डिबग मोड में उपस्थित होने के लिए है? वीबी दोनों मोड में समान कार्य करता है, और सी # सामान्य पैरामीटर के बिना विधि को कॉल करते समय अतिरिक्त निर्देश नहीं डालता है (जब आप वैकल्पिक पैरामीटर का उपयोग करते हैं)।

+0

पैरामीटर पर स्विच ऑर्डर करें, फू (बी: = "बी", ए: = "ए") अंतर देखने के लिए (संकेत: साइड इफेक्ट ऑर्डर) – adrianm

+0

बराबर वीबी कोड क्या है? –

+0

@adrianm एक दिलचस्प विचार है, लेकिन मैंने अभी कोशिश की है (जिज्ञासा से बाहर) और जो एक ही आईएल को 'फू (ए: "ए", बी: "बी") के रूप में उत्पन्न करता है; ' –

उत्तर

13

क्या उनके लिए डिबग मोड में मौजूद होने का कोई विशेष कारण है?

अंतर के बीच है:

  • धक्का ढेर पर एक अस्थायी मूल्य,, इसका इस्तेमाल इसे त्यागने, और
  • दुकान एक विशिष्ट ढेर स्लॉट में एक अस्थायी मूल्य है, यह की एक प्रतिलिपि बनाने ढेर पर, इसका इस्तेमाल इसे त्यागने, लेकिन अस्थायी मूल्य की मूल प्रति ढेर स्लॉट में रहता है

इस अंतर के दृश्य प्रभाव है कि कचरा कलेक्टर को साफ करने के बारे में के रूप में आक्रामक नहीं किया जा सकता है महत्व। पहले परिदृश्य में, कॉल रिटर्न के तुरंत बाद मूल्य एकत्र किया जा सकता है। दूसरे परिदृश्य में, मान केवल वर्तमान विधि रिटर्न के बाद एकत्र किया जाता है (या स्लॉट का पुन: उपयोग किया जाता है)।

कचरा कलेक्टर कम आक्रामक बनाना अक्सर डीबग परिदृश्यों में मदद करता है।

गर्भित सवाल यह है:

क्यों सी # और VB के बीच क्या अंतर है?

सी # और वीबी कंपाइलर्स अलग-अलग लोगों द्वारा लिखे गए थे जिन्होंने अपने संबंधित कोड जेनरेटर कैसे काम करते हैं, इस बारे में अलग-अलग विकल्प बनाये।

अद्यतन: पुन: अपनी टिप्पणी

सी # संकलक में, unoptimized आईएल पीढ़ी सुविधा के बारे में हमारी आंतरिक प्रतिनिधित्व के रूप में एक ही संरचना का अनिवार्य रूप से है। जब हम किसी नामित तर्क देखें:

M(y : Q(), x : R()); 

जहां विधि है, कहते हैं कि

void M(int x, int y) { } 

हम इस प्रतिनिधित्व आंतरिक रूप से है जैसे कि आप लिखा था

int ytemp = Q(); 
int xtemp = R(); 
M(xtemp, ytemp); 

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

जब हम ऑप्टिमाइज़र चलाते हैं तो हम सभी प्रकार की चीजों का पता लगाते हैं - जैसे तथ्य यह है कि कोई भी किसी भी चीज़ के लिए उन अदृश्य स्थानीय चर का उपयोग नहीं करता है। फिर हम कोडेजन से स्थानीय लोगों को खत्म कर सकते हैं।

मुझे वीबी आंतरिक प्रतिनिधित्व के बारे में बहुत कम पता है; मैंने 1 99 5 से वीबी कंपाइलर पर काम नहीं किया है, और मैंने सुना है कि यह पिछले पंद्रह वर्षों में थोड़ा सा बदल सकता है। मैं कल्पना करता हूं कि वे कुछ ऐसा ही करते हैं, लेकिन मुझे यह नहीं पता कि वे नामित पैरामीटर का प्रतिनिधित्व कैसे करते हैं या उनके कोड जनरेटर उनके साथ कैसे व्यवहार करते हैं।

मेरा मुद्दा यह है कि यह अंतर मेरे ज्ञान के लिए, एक महत्वपूर्ण अर्थपूर्ण अंतर को चित्रित नहीं करता है। इसके बजाय, यह दिखाता है कि नॉनोप्टाइमिज्ड बिल्ड केवल जेनरेट करने के लिए जो भी उच्च स्तरीय आंतरिक प्रतिनिधित्व उत्पन्न करता है, उसे पता चलता है कि हम जानते हैं कि वांछित अर्थशास्त्र है।

+1

@Eric यह एक अच्छा स्पष्टीकरण है, धन्यवाद! निहित प्रश्न के लिए, मेरा मतलब यह था कि "उन्होंने उन विकल्पों को क्यों चुना" क्योंकि मैंने माना कि ऐसा करने के अच्छे कारण थे। –

+0

+1 बाएं से दाएं मूल्यांकन पर जोर देने के लिए जो आप लोगों को लगातार बनाए रखने के लिए सी # में धार्मिक रूप से पालन करना प्रतीत होता है (इसके अलावा आपके एफ() + जी() * एच() उदाहरण को दूसरे जवाब में संदर्भित करता है) –

5

संकलक निम्नलिखित सी # कोड का उत्पादन:

नहीं - संकलक आईएल, जिसे फिर आप सी # करने के लिए अनुवाद कर रहे हैं पैदा करता है। सी # कोड के लिए कोई समानता पूरी तरह आकस्मिक है (और सभी जेनरेट आईएल सी # के रूप में लिखे जा सकते हैं)। उन सभी "एनओपी" की उपस्थिति मुझे बताती है कि आप "डीबग" मोड में हैं। मैं "रिलीज" मोड में पुनः प्रयास करूंगा - इससे इन चीजों में बड़ा अंतर हो सकता है।

मैं इसे रिलीज़ मोड में ऊपर निकाल दिया, का उपयोग करते हुए:

static void Main() 
{ 
    Foo(a: "a", b: "b"); 
} 

देते:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 8 
    L_0000: ldstr "a" 
    L_0005: ldstr "b" 
    L_000a: call void ConsoleApplication1.Program::Foo(string, string) 
    L_000f: ret 
} 

तो समान।

+0

आप सही हैं, मेरे पास पिछली भाषा थी ... अच्छी पकड़। मैंने रिलीज मोड में फिर से कोशिश की (जिसे मैंने सोचा था कि मैंने कोशिश की थी, लेकिन ऐसा लगता है कि मैंने नहीं किया था)। सी # आईएल निर्देश उस मोड में वीबी वाले से मेल खाते हैं। यह अभी भी मुझे आश्चर्यचकित करता है कि तर्क डीबग मोड में अतिरिक्त निर्देशों के उत्पादन के लिए क्या कारण है, क्योंकि वीबी दोनों मोडों में इसे छोटा रास्ता मानता है, लेकिन यह जानना अच्छा है कि यह रिलीज मोड में कोई मुद्दा नहीं है। –

+0

@gshackles - मुझे लगता है कि आंतरिक रूप से यह सबसे सरल व्याख्या का उपयोग करता है जो अनुवाद चरण (यानी आपके प्रश्न में संस्करण) के दौरान * शुद्धता की गारंटी देता है, और उसके बाद इसे अनुकूलित करने के लिए संकलक में बाद में (वैकल्पिक) चरणों पर निर्भर करता है। बहुत शाब्दिक कोड अनुवाद होने से डिबगर्स को सरल और अधिक विश्वसनीय बनाता है। –

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