क्या रिटर्न myVar बनाम रिटर्न (myVar) के बीच अंतर है?


87

मैं कुछ उदाहरण C # कोड को देख रहा था, और देखा कि एक उदाहरण ने () के रिटर्न को लपेट दिया।

मैंने हमेशा किया है:

return myRV;

क्या कोई अंतर है:

return (myRV);

जवाबों:


229

अद्यतन: यह प्रश्न 12 अप्रैल 2010 को मेरे ब्लॉग का विषय था । मनोरंजक सवाल के लिए धन्यवाद!

व्यवहार में, कोई अंतर नहीं है।

में सिद्धांत अंतर हो सकता है। C # स्पेसिफिकेशन में तीन दिलचस्प बिंदु हैं जहां यह अंतर पेश कर सकता है।

सबसे पहले, प्रकार और अभिव्यक्ति पेड़ों को सौंपने के लिए अनाम कार्यों का रूपांतरण। निम्नलिखित को धयान मे रखते हुए:

Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }

F1स्पष्ट रूप से कानूनी है। है F2? तकनीकी रूप से, नहीं। कल्पना धारा 6.5 में कहती है कि एक लंबोदर अभिव्यक्ति से एक संगत प्रतिनिधि प्रकार में रूपांतरण होता है । क्या वह लंबोदर अभिव्यक्ति है ? नहीं, यह एक लंबित अभिव्यक्ति है जिसमें लंबोदर अभिव्यक्ति है

विज़ुअल सी # कंपाइलर यहां एक छोटा कल्पना उल्लंघन करता है और आपके लिए कोष्ठक को छोड़ देता है।

दूसरा:

int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }

F3कानूनी ही। हैF4 ? सं। 7.5.3 में कहा गया है कि एक कोष्ठक की अभिव्यक्ति में विधि समूह नहीं हो सकता है। फिर, आपकी सुविधा के लिए हम विनिर्देश का उल्लंघन करते हैं और रूपांतरण की अनुमति देते हैं।

तीसरा:

enum E { None }
E F5() { return 0; }
E F6() { return (0); }

F5कानूनी ही। है F6? नहीं। कल्पना में कहा गया है कि शाब्दिक शून्य से किसी भी प्रकार के रूपांतरण होते हैं। "(0) " शाब्दिक शून्य नहीं है, यह एक शाब्दिक शून्य है जिसके बाद शाब्दिक शून्य है, इसके बाद एक कोष्ठक है। हम यहां विनिर्देश का उल्लंघन करते हैं और वास्तव में किसी भी संकलन समय स्थिर अभिव्यक्ति को शून्य के बराबर अनुमति देते हैं , और न केवल शाब्दिक शून्य।

तो हर मामले में, हम आपको इससे दूर होने की अनुमति देते हैं, भले ही तकनीकी रूप से ऐसा करना अवैध है।


12
@ जेसन: मेरा मानना ​​है कि पहले दो मामलों में कल्पना का उल्लंघन केवल त्रुटियां हैं जिन्हें कभी नहीं पकड़ा गया। प्रारंभिक रूप से बाध्यकारी पास ऐतिहासिक रूप से समय से पहले अभिव्यक्तियों के अनुकूलन के बारे में बहुत आक्रामक रहा है, और इसका एक परिणाम यह है कि कोष्ठक बहुत जल्दी फेंक दिए जाते हैं, इससे पहले कि वे होना चाहिए। बहुत अधिक हर मामले में, यह सब कुछ ऐसे कार्यक्रम बनाता है जो सहज रूप से स्पष्ट रूप से काम करते हैं जिस तरह से उन्हें करना चाहिए, इसलिए मैं इसके बारे में बहुत चिंतित नहीं हूं। तीसरे मामले का विश्लेषण यहाँ है: blogs.msdn.com/ericlippert/archive/2006/03/28/…
एरिक

6
सिद्धांत रूप में, व्यवहार में, वहाँ है एक अंतर (मैं नहीं कर रहा हूँ यकीन है कि अगर मोनो इन 3 मामलों की अनुमति देता है, और किसी अन्य सी # संकलक का पता नहीं है, तो वहाँ या व्यवहार में व्यवहार में एक अंतर नहीं हो सकता)। C # कल्पना का उल्लंघन करने का मतलब है कि आपका कोड पूरी तरह से पोर्टेबल नहीं होगा। विजुअल C # के विपरीत कुछ C # कंपाइलर उन विशेष मामलों में युक्ति का उल्लंघन नहीं कर सकते हैं।
ब्रायन

18
@ ब्रूनो: इसमें लगने वाला समय किसी दिए गए विषय का आठ या दस हजार घंटे का अध्ययन है और आप भी इसके विशेषज्ञ हो सकते हैं। चार साल के पूर्णकालिक काम में यह आसानी से संभव है।
एरिक लिपर्ट

32
@ एंथनी: जब मैं ऐसा करता हूं तो मैं सिर्फ लोगों को बताता हूं कि मेरी डिग्री गणित में है , अंकगणित में नहीं ।
एरिक लिपर्ट

7
सिद्धांत रूप में, अभ्यास और सिद्धांत समान हैं, लेकिन प्रतिज्ञा में वे कभी नहीं होते हैं।
इब्राहिम हाशिमी

40

कोने के मामले हैं जब कोष्ठक की उपस्थिति कार्यक्रम के व्यवहार पर प्रभाव डाल सकती है:

1।

using System;

class A
{
    static void Foo(string x, Action<Action> y) { Console.WriteLine(1); }
    static void Foo(object x, Func<Func<int>, int> y) { Console.WriteLine(2); }

    static void Main()
    {
        Foo(null, x => x()); // Prints 1
        Foo(null, x => (x())); // Prints 2
    }
}

2।

using System;

class A
{
    public A Select(Func<A, A> f)
    {
        Console.WriteLine(1);
        return new A();
    }

    public A Where(Func<A, bool> f)
    {
        return new A();
    }

    static void Main()
    {
        object x;
        x = from y in new A() where true select (y); // Prints 1
        x = from y in new A() where true select y; // Prints nothing
    }
}

3।

using System;

class Program
{
    static void Main()
    {
        Bar(x => (x).Foo(), ""); // Prints 1
        Bar(x => ((x).Foo)(), ""); // Prints 2
    }

    static void Bar(Action<C<int>> x, string y) { Console.WriteLine(1); }
    static void Bar(Action<C<Action>> x, object y) { Console.WriteLine(2); }
}

static class B
{
    public static void Foo(this object x) { }
}

class C<T>
{
    public T Foo;
}

आशा है कि आप इसे व्यवहार में कभी नहीं देखेंगे।


मेरे सवाल का बिल्कुल जवाब नहीं है, लेकिन अभी भी दिलचस्प है - धन्यवाद।
क्रिस

1
क्या आप बता सकते हैं कि यहां 2 में क्या चल रहा है?
एरिक

2
आपको इस बारे में विस्तार से बताना चाहिए कि यह व्यवहार क्यों होता है।
आर्टुरो टॉरेस सेंचेज

26

नहीं, वाक्य-रचना के अलावा कोई अंतर नहीं है।


3

इस तरह के सवालों का जवाब देने का एक अच्छा तरीका रिफ्लेक्टर का उपयोग करना है और देखें कि आईएल क्या उत्पन्न करता है। आप कंपाइल ऑप्टिमाइज़ेशन और इस तरह की असेंबलिंग असेंबलियों के बारे में बहुत कुछ सीख सकते हैं।


6
यह निश्चित रूप से एक विशिष्ट मामले के लिए प्रश्न का उत्तर देगा, लेकिन यह जरूरी नहीं कि स्थिति की संपूर्णता का प्रतिनिधि होगा।
20

सहमत नहीं हैं। यह व्यक्ति को प्रश्न का उत्तर देने की दिशा देता है।
ब्रायन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.