क्या C # पढ़ना कठिन होता जा रहा है?


15

जैसा कि C # ने प्रगति की है, कई भाषा सुविधाएँ जोड़ी गई हैं। यह उस बिंदु पर आ गया है जहां यह मेरे लिए अपठनीय हो रहा है।

एक उदाहरण के रूप में, यहां Caliburn.Micro कोड से निम्नलिखित कोड स्निप पर विचार करें :

            container = CompositionHost.Initialize(
                   new AggregateCatalog(
                      AssemblySource.Instance.
                             Select(x => new AssemblyCatalog(x))
                               .OfType<ComposablePartCatalog>()
                )
            );

अब, यह केवल एक छोटा सा उदाहरण है।

मेरे पास कई प्रश्न हैं:

  • क्या यह एक आम या ज्ञात समस्या है?
  • क्या C # समुदाय समान है?
  • क्या यह भाषा के साथ एक मुद्दा है, या क्या यह डेवलपर द्वारा उपयोग की जाने वाली शैली है?

क्या दूसरों के कोड को बेहतर ढंग से समझने और इस तरह से कोड लिखने से बचने के लिए कोई सरल उपाय हैं?


6
इसका लंबो कार्य, वे तब तक पढ़ना कठिन है जब तक आप वास्तव में उन्हें प्राप्त नहीं करते।
रायथल

9
मुझे लगता है कि आपने वास्तव में सिंटैक्स के बारे में नहीं सोचा था। अभ्यास के साथ आपका उदाहरण पढ़ना सरल है।
ChaosPandion

6
@ थोमस ओवेन्स: पवित्र शिट मैन, कम से कम हमें कुछ समय दें कि हम उन्हें खुला रखने के लिए प्रश्नों को संपादित कर सकें। 15 मिनट? चलो भी अब।
स्टीवन एवर्स

4
@DannyVarod: 1. "नहीं" स्वीकार्य उत्तर नहीं है। 2. प्रश्न बंद हो गया है। 3. यदि आप सहमत हैं कि प्रश्न यहां नहीं होना चाहिए तो इसे बंद करने के लिए ध्वज / वोट दें या इसे बेहतर बनाने के लिए संपादित करें
स्टीवन एवर्स

2
@ Thorbjørn रावन एंडरसन - एक थप्पड़ से कोई क्या सीख सकता है? इसमें कोई जानकारी नहीं है!

जवाबों:


12

त्वरित नोट जहां भाषा को इसे स्पष्ट करना चाहिए: C # एक सामान्य प्रयोजन प्रोग्रामिंग भाषा है ; सी के विपरीत (सी ++ की तरह) यह उच्च अमूर्तता के लिए प्रयास करता है; लिस्प बोलियों के विपरीत, इसका उद्देश्य व्यावहारिक अभिव्यंजना के लिए है, और, जावा के विपरीत, यह अधिक आक्रामक रूप से संचालित है - मांग की प्रतिक्रिया के लिए Microsoft त्वरित है।

यही कारण है कि यह LINQ, लैम्ब्डा और अजीब नए कीवर्ड के मिश्रण में बदल रहा है - यह नई समस्या डोमेन के लिए जल्दी से आदत डाल रहा है, और यह वास्तव में एक भाषा की ओर एक फिसलन ढलान है जो इतनी जटिल है कि बहुत कम लोग इसे सही तरीके से उपयोग कर सकते हैं (जैसे कि + ++)। यह सी # के साथ कोई समस्या नहीं है, यह इन महत्वाकांक्षी लक्ष्यों के साथ किसी भी भाषा के साथ एक समस्या है।

समुदाय को इसके बारे में पता है और इससे भी महत्वपूर्ण बात यह है कि C # के पीछे वाले लोग इसके बारे में पूरी तरह से जानते हैं (कुछ ब्लॉग प्रविष्टियाँ और C # 5.0 में नए परिवर्धन के पीछे क्या पॉडकास्ट दिखाते हैं कि ये लोग कितनी सरल चीजों को सरल रखना चाहते हैं)। Microsoft अपने फ्लैगशिप को कुछ इस तरह लोड करने की कोशिश कर रहा है कि यह एक टारपीट न बन जाए: DLR की शुरूआत, नई भाषाओं पर एक उज्ज्वल स्पॉटलाइट (F #)।

इसके अलावा, सी # पर पाठ्यक्रम सामग्री (एमएस प्रमाणपत्र सहित) सी के लिए उपयोग की अलग (लेकिन सुसंगत) शैलियों की सिफारिश करती है - समस्या के आधार पर - अपना हथियार चुनें और उस पर चिपके रहें: कुछ समस्याओं पर धाराप्रवाह शैली LINQ, दूसरों के साथ TPL के साथ लंबोदा, सादा -अधिकतम के लिए बताया।


2
क्या आप बता सकते हैं कि "लिस्प बोलियों के विपरीत इसका अर्थ व्यावहारिक अभिव्यक्ति के लिए करना है" क्या है?
जियोर्जियो

27

नंबर सी # हमें अधिक सुसाइड करने के लिए कोड लिखने के लिए अधिक विकल्प दे रहा है। इसका उपयोग या दुरुपयोग किया जा सकता है। अगर इसका सही इस्तेमाल किया जाए तो यह कोड को पढ़ना आसान बनाता है। यदि अनुचित तरीके से उपयोग किया जाता है तो यह कोड को पढ़ने में कठिन बना सकता है। लेकिन बुरे प्रोग्रामर के पास कोड को पढ़ने के लिए लिखने में हमेशा एक कौशल होता है।

दो उदाहरण लेते हैं, दोनों एक ही समस्या के बारे में StackOverflow पर पाए गए उदाहरणों के आधार पर, एक विशिष्ट विशेषता के साथ प्रकार ढूंढते हैं:

सी # 2.0:

static IEnumerable<Type> GetTypesWithAttribute<TAttribute>(bool inherit) 
                              where TAttribute: System.Attribute
{
    foreach(Assembly assembly in AppDomain.Current.GetAssemblies())
    {
        foreach(Type type in assembly.GetTypes()) 
        {
            if (type.IsDefined(typeof(TAttribute),inherit))
                yield return type;
        }
    }
}

C # 4.0:

IEnumerable<Type> GetTypesWith<TAttribute>(bool inherit) 
                              where TAttribute: System.Attribute
{ 
    return from assembly in AppDomain.CurrentDomain.GetAssemblies()
           from type in assembly.GetTypes()
           where type.IsDefined(typeof(TAttribute),inherit)
           select type;
}

IMHO, नया सिंटैक्स पढ़ने में बहुत आसान बनाता है।


नया सिंटैक्स वास्तव में पढ़ना आसान है, लेकिन समझने में आसान है, जैसे कि हुड के नीचे क्या चल रहा है? पहला उदाहरण समझने योग्य है, दूसरा अधिक पठनीय है।
नवाफल

4
@nawfal मेरे अनुभव में, लोगों को लाइनक बयानों की तुलना में "यील्ड रिटर्न" निर्माण को समझने में अधिक परेशानी होती है; इसलिए मैं तर्क दूंगा कि दूसरा अधिक पठनीय और समझने योग्य है। न तो वास्तव में आपको बताता है कि हुड के नीचे क्या चल रहा है, क्योंकि दोनों मानचित्र अमूर्तता से बहुत दूर हैं कि प्रोसेसर वास्तव में कैसे काम करते हैं।
चू

ईमानदार होने के लिए, मैं LINQ को नापसंद करता हूं क्योंकि यह सार को दूर करता है और अधिक जटिल कोर के साथ एक लूप के बजाय अलग-अलग LINQ प्रश्नों (पृष्ठभूमि में अलग लूप के साथ) में डेटा प्राप्त करने के लिए कोडर्स को दूर करता है और प्रोत्साहित करता है।
15:30 बजे mg30rg

8

जब LINQ जोड़ा गया था, तो यह बहुत सारे फ़्लुएंट-स्टाइल मेथड को शामिल करते हुए कोडिंग की एक शैली को लोकप्रिय बना दिया, और लैम्बडा को पैरामीटर के रूप में पारित किया।

एक बार जब आप इसके साथ सहज हो जाते हैं तो यह शैली बहुत शक्तिशाली होती है। हालाँकि इसे अपठनीय कोड बनाने के लिए दुरुपयोग किया जा सकता है। मुझे नहीं लगता कि आपका उदाहरण बहुत बुरा है, हालांकि इंडेंटेशन यादृच्छिक की तरह है (और यह कोड की इस शैली की एक सामान्य विशेषता है, विजुअल स्टूडियो इसे लगातार ऑटो-इंडेंट नहीं करता है)।

मेरे कार्यस्थल पर, हमने इस वर्ष की शुरुआत में अपने कोडिंग मानकों की समीक्षा करते समय इस कोडिंग शैली पर चर्चा की, और हमने डेवलपर्स को इस तरह कोड को तोड़ने के लिए प्रोत्साहित करने का फैसला किया: विशेष रूप से, फ़ंक्शन कॉल के भीतर अनाम ऑब्जेक्ट बनाने और शुरू करने के लिए नहीं। तो आपका कोड बन जाएगा:

var assemblyCatalog = AssemblySource.Instance
    .Select(x => new AssemblyCatalog(x))
    .OfType<ComposablePartCatalog>();
var aggregateCatalog = new AggregateCatalog(assemblyCatalog);
container = CompositionHost.Initialize(aggregateCatalog);

1
क्या एक नए प्रकार का निर्माण करना अजीब नहीं है, और फिर उस प्रकार से गतिशील रूप से सही बाद में स्विच करना है?
डेडएमजी

शायद, मैंने अभी कोड स्निपेट को बिना किसी वास्तविक विचार के काट दिया था कि इसका इरादा क्या था। कोड के लुक पर क्या असर होगा, यह दिखाने के लिए बस कोड के सभी लाइनों में से सभी को अलग करना चाहता था।
कार्सन63000

मैं मांगपत्र का दोष लेता हूं :()। यहाँ मूल है: devlicio.us/blogs/rob_eisenberg/archive/2010/07/08/…

1
मैं उस जवाब से पूरी तरह सहमत हूं। कोड के उदाहरण टुकड़े में समस्या नई सी # वाक्य रचना नहीं है, इसका यह है कि लेखक ने "एक-लाइनर" कोड के साथ चतुर होने की कोशिश की। UNIX से वापस डेटिंग करने का यह पुराना नियम है: सब कुछ केवल एक ही करना चाहिए , और इसे अच्छी तरह से करना चाहिए। यह कक्षा पर लागू होता है, यह विधि पर लागू होता है और निश्चित रूप से, यह सबसे निश्चित रूप से कोड की लाइनों पर लागू होता है।
लॉरेंट बॉर्गुल्ट-रॉय

4

आपके उदाहरण में कोड आसानी से पढ़ने योग्य नहीं है क्योंकि

  • यह कई धारणाओं (संरचना, कैटलॉग, एग्रीगेट्स, असेंबली, कॉन्सटेबलपार्ट्स ...) को कई स्तरों के घोंसले के साथ मिलाता है जबकि कॉलिंग कोड को आमतौर पर केवल एक स्तर से निपटना चाहिए। उप-संपत्तियों की एक श्रृंखला के बजाय केवल नेस्टेड विधि कॉल के साथ कानून के कानून के उल्लंघन का एक सा लगता है। यह कोड की लाइन के पीछे के इरादे को कुछ हद तक गड़बड़ कर देता है।

  • एक अजीब सिंगलटन उपयोग है - AssemblySource.Instance.Select()इसका मतलब है कि इंस्टेंस एक IEnumerable है, जो थोड़ा अजीब है।

  • लैम्ब्डा एक्सप्रेशन में एक्स वेरिएबल बदसूरत है। आम तौर पर आप अपने लैम्ब्डा वेरिएबल्स के इरादे को नाम देने की कोशिश करते हैं - पाठक को यह पहचानने में मदद करता है कि फ़ंक्शन किस तरह का डेटा है, भले ही वह लैम्ब्डा से परिचित न हो।

  • यह स्पष्ट नहीं है कि आपको उन OfType<T>()वस्तुओं के संग्रह के साथ फ़िल्टर क्यों करना चाहिए जिन्हें आपने अभी-अभी नया बनाया है ...

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

अधिक आम तौर पर, यह मदद करता है अगर आपके कोड का पाठक जानता है कि लैम्ब्डा कैसे काम करता है, लेकिन स्पष्ट रूप से पर्याप्त नामकरण के साथ आप लगभग हमेशा अपने कोड को पूर्व-.NET 3.5 पृष्ठभूमि वाले किसी व्यक्ति के लिए भी पठनीय बनाने का प्रबंधन करते हैं।


2

कभी भी लोकप्रिय भाषा का एक नया संस्करण नए निर्माणों को प्राप्त करता है, इसी तरह की बहसें होती हैं।

मुझे भी ये शंकाएँ वर्षों पहले हुई थीं (http://gsscoder.blogspot.it/2009/08/use-csharps-features-witely.html)।

मेरी राय में C # एक सुरुचिपूर्ण और सुसंगत तरीके से विकसित हो रहा है।

आपके नमूने में कोड जटिल नहीं है, हो सकता है कि आप लैमडा के भाव के साथ उपयोग नहीं किए गए हों।

समस्या यह है कि C # केवल एक ऑब्जेक्ट ओरिएंटेड भाषा नहीं है, यह अब कार्यात्मक कंस्ट्रक्शन (http://archive.msdn.microsoft.com/FunctionalCSharp/) का भी समर्थन करता है।


1

लैंबडा सिंटैक्स को समझने में मुझे थोड़ा समय लगा, और मैं एक गणित और भौतिक पृष्ठभूमि से हूं। यह गणितीय अभिव्यक्तियों के समान है, इसके अलावा वे उपयोग करते हैं -> के बजाय =>:

मैथ्स उदाहरण f (x): = x-> x + 2 इसे पढ़ता है "x के फ़ंक्शन f को x मानचित्र पर x + 2 के रूप में परिभाषित किया गया है

c # उदाहरण del myDelegate = x => x +2; यह पढ़ता है "myDelegate एक फ़ंक्शन है जैसे कि myDelegate (x) x से x + 2 पर मैप करता है

गणित और प्रोग्रामिंग के बीच असंगतता वास्तव में मदद नहीं करती है, हालांकि मुझे लगता है -> पहले से ही C ++ में "संपत्ति" (urrgghh!) के रूप में लिया गया था।

http://en.wikipedia.org/wiki/List_of_mathematical_symbols


"हालांकि मुझे लगता है -> पहले से ही C ++ में" संपत्ति "(urrgghh!) के रूप में लिया गया था" जैसा कि! पूरी तरह से C ++ में इसका मतलब है "गतिशील रूप से आवंटित की गई संपत्ति ..."। यदि कोई चीज़ गतिशील नहीं है, तो आप हर दूसरी भाषा की तरह अवधि का उपयोग करते हैं।
15:30 बजे mg30rg
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.