C # (.NET) डिज़ाइन फ़्लास [बंद]


84

सामान्य रूप से C # या .NET फ्रेमवर्क में कुछ सबसे बड़े डिज़ाइन दोष क्या हैं?

उदाहरण: कोई गैर-अशक्त स्ट्रिंग प्रकार नहीं है और IDataReader से मान प्राप्त करते समय आपको DBNull की जांच करनी होगी।


किस अर्थ में वे डिज़ाइन दोष हैं?
— जूलियट

IDataReader के साथ आप बल्कि मैन्युअल रूप से जाँच से IsDBNull उपयोग कर सकते हैं
— मार्क Gravell

9
क्यू जॉन स्कीट सीलबंद कक्षाओं के बारे में बात करने के लिए;)
— 23

3
IDataReader को विस्तार विधि से ठीक करना बहुत आसान है: weblogs.asp.net/skillet/archive/2008/06/18/… देखें ।
— राबर्ट रोसनी

@lagerdalek - अगर मैं कर सकता तो मैं +1 टिप्पणी करता हूं; अच्छी तरह से याद आया
— मार्क Gravell

जवाबों:


39

मैं इस पोस्ट के साथ सशक्त रूप से सहमत हूं (उन लोगों के लिए, जो ToString की कमी की पूजा करते हैं, आपकी कक्षा के लिए एक कस्टम प्रारूप प्रदान करने के लिए डिबगर विशेषता है)।

उपरोक्त सूची के शीर्ष पर, मैं निम्नलिखित उचित अनुरोध भी जोड़ूंगा:

  1. अशक्त मान प्रकारों के पूरक के रूप में अशक्त संदर्भ प्रकार,
  2. किसी रचना के खाली निर्माता को ओवरराइड करने की अनुमति दें,
  3. सीलबंद कक्षाओं को निर्दिष्ट करने के लिए सामान्य प्रकार की बाधाओं को अनुमति दें,
  4. मैं यहां एक और पोस्टर से सहमत हूं, जो बाधाओं के रूप में इस्तेमाल होने पर मनमाने ढंग से निर्माण करने वाले हस्ताक्षरों का अनुरोध करता है। कहाँ T : new(string), या कहाँT : new(string, int)
  5. मैं एक और पोस्टर के साथ यहां फिक्सिंग घटनाओं के बारे में भी सहमत हूं, दोनों खाली ईवेंट सूचियों के लिए और समवर्ती सेटिंग में (हालांकि बाद वाला आकर्षक है,)
  6. ऑपरेटरों को विस्तार विधियों के रूप में परिभाषित किया जाना चाहिए, और वर्ग के स्थिर तरीकों के रूप में नहीं (या कम से कम स्थिर तरीकों के रूप में नहीं),
  7. इंटरफेस के लिए स्थिर गुणों और विधियों की अनुमति दें (जावा में यह है, लेकिन C # नहीं है),
  8. ऑब्जेक्ट आरंभीकरण में घटना की अनुमति दें (केवल फ़ील्ड और गुण वर्तमान में अनुमत हैं),
  9. "ऑब्जेक्ट इनिशियलाइज़र" सिंटैक्स केवल ऑब्जेक्ट बनाते समय प्रयोग करने योग्य क्यों होता है? क्यों नहीं इसे किसी भी समय उपलब्ध कराया जाए, अर्थात।var e = new Foo(); e { Bar = baz };
  10. द्विघात व्यवहार को ठीक करें ,
  11. सभी संग्रहों में पुनरावृत्ति के लिए अपरिवर्तनीय स्नैपशॉट होना चाहिए (अर्थात। संग्रह को संशोधित करने से पुनरावृत्त को अमान्य नहीं करना चाहिए),
  12. tuples को जोड़ना आसान है, लेकिन एक कुशल बंद बीजगणितीय प्रकार जैसे " Either<T>" नहीं है, इसलिए मुझे बंद बीजीय प्रकार को घोषित करने और उस पर मेल खाने वाले संपूर्ण पैटर्न को लागू करने का कुछ तरीका पसंद आएगा (मूल रूप से आगंतुक पैटर्न के लिए प्रथम श्रेणी का समर्थन, लेकिन कहीं अधिक कुशल); तो बस enums ले लो, उन्हें विस्तृत पैटर्न मिलान समर्थन के साथ विस्तारित करें, और अमान्य मामलों की अनुमति न दें,
  13. मुझे सामान्य रूप से मेल खाने वाले पैटर्न के लिए समर्थन पसंद है, लेकिन ऑब्जेक्ट प्रकार के परीक्षण के लिए बहुत कम से कम; मैं भी एक और पोस्ट में प्रस्तावित सिंटैक्स को पसंद करता हूं,
  14. मैं एक और पोस्ट से सहमत हूं कि System.IOकक्षाएं, जैसे Stream, कुछ खराब तरीके से डिज़ाइन की गई हैं; किसी भी इंटरफ़ेस जिसे फेंकने के लिए कुछ कार्यान्वयन की आवश्यकता होती NotSupportedExceptionहै, एक खराब डिज़ाइन है,
  15. IListकी तुलना में यह बहुत सरल होना चाहिए; वास्तव में, यह कई ठोस संग्रह इंटरफेस के लिए सही हो सकता है, जैसे ICollection,
  16. उदाहरण के लिए, IDEDIA जैसे अपवादों को फेंकने के बहुत सारे तरीके
  17. मैं जावा में उपलब्ध तुलना में बेहतर तरीके से जांचे गए अपवादों को पसंद करूंगा (यह कैसे किया जा सकता है, इसके लिए प्रकार और प्रभाव प्रणाली पर शोध देखें),
  18. जेनेरिक विधि अधिभार संकल्प में विभिन्न कष्टप्रद कोने मामलों को ठीक; उदाहरण के लिए, दो अतिभारित विस्तार विधियों को प्रदान करने का प्रयास करें, एक जो संदर्भ प्रकारों पर काम करता है, और दूसरा अशक्त संरचना प्रकारों पर, और देखें कि आपके प्रकार का अनुमान कैसा लगता है,
  19. इंटरफेस पर फ़ील्ड और सदस्य नामों को सुरक्षित रूप से प्रतिबिंबित करने का एक तरीका प्रदान करता है INotifyPropertyChanged, जैसे कि फ़ील्ड नाम को स्ट्रिंग के रूप में लेना; आप एक विस्तार विधि का उपयोग करके ऐसा कर सकते हैं जो एक MemberExpression, यानी के साथ एक लंबोदर लेता है । () => Foo, लेकिन यह बहुत कुशल नहीं है,
    • अपडेट: C # 6.0 ने nameof()एकल सदस्य नामों के लिए ऑपरेटर को जोड़ा , लेकिन यह जेनरिक में काम नहीं करता ( nameof(T) == "T"वास्तविक प्रकार-तर्क के नाम के बजाय: आपको अभी भी करने की आवश्यकता है typeof(T).Name)) - और न ही यह आपको "पथ" स्ट्रिंग प्राप्त करने की अनुमति देता है , जैसे nameof(this.ComplexProperty.Value) == "Value"इसके संभावित अनुप्रयोगों को सीमित करना।
  20. इंटरफेस में ऑपरेटरों को अनुमति दें, और सभी कोर नंबर प्रकारों को लागू करें IArithmetic; अन्य उपयोगी साझा ऑपरेटर इंटरफेस भी संभव हैं,
  21. ऑब्जेक्ट फ़ील्ड्स / प्रॉपर्टीज़ को म्यूट करना या बहुत कम से कम, अपरिवर्तनीय फ़ील्ड्स को एनोटेट करने की अनुमति देना और टाइप चेकर को लागू करने की अनुमति देना (बस इसे गेट्टर-ओनली प्रॉपर्टी फ़ेर क्रिसिस के रूप में मानें, यह कठिन नहीं है!) वास्तव में, दोनों को होने का कोई मतलब नहीं है क्योंकि खेतों और संपत्तियों को अधिक समझदार तरीके से एकीकृत करें; C # 3.0 के स्वचालित गुण इस दिशा में एक पहला कदम है, लेकिन वे बहुत दूर नहीं जाते हैं,
    • अद्यतन: जबकि C # में readonlyकीवर्ड था, और C # 6.0 ने केवल-पढ़ने के लिए ऑटो-गुण जोड़े, हालांकि यह अपरिवर्तनीय प्रकारों और मूल्यों के लिए सही भाषा समर्थन जितना कठोर नहीं है।
  22. निर्माणकर्ताओं की घोषणा को सरल बनाना; मुझे F # का दृष्टिकोण पसंद है, लेकिन यहां दूसरे पद के लिए वर्ग नाम के बजाय बस "नए" की आवश्यकता है, कम से कम,

बस इतना ही काफी है। ये सभी परेशानियां हैं जो मैंने पिछले सप्ताह में की हैं। मैं शायद घंटों तक जा सकता था अगर मैं वास्तव में अपना दिमाग लगाता। C # 4.0 पहले से ही नाम, वैकल्पिक और डिफ़ॉल्ट तर्क जोड़ रहा है, जिसे मैं सशक्त रूप से अनुमोदित करता हूं।

अब एक अनुचित अनुरोध के लिए:

  1. यह वास्तव में अच्छा होगा , अगर C # / CLR, कंस्ट्रक्टर पॉलीमॉर्फिज़्म का समर्थन कर सकता है, अर्थात। जेनेरिक से अधिक जेनेरिक,

मान जाओ ना? :-)


1
# 1 के संबंध में, हर प्रकार का या तो कुछ डिफ़ॉल्ट मान होना चाहिए, या किसी विशेष प्रकार का चर या फ़ील्ड आवंटित होने पर सिस्टम को एक कंस्ट्रक्टर चलाने का साधन प्रदान करना होगा। मैं बाद वाला (# 2 का ऑफशूट) पसंद करूंगा, लेकिन # 1 को समायोजित किया जा सकता है यदि गैर-आभासी तरीकों / गुणों को यह निर्दिष्ट करने के लिए सजाया जा सकता है कि उन्हें बिना जांच के बुलाया जाना चाहिए। यह "स्ट्रिंग" फ़ील्ड जैसी चीज़ों को व्यवहार करने की अनुमति देगा, हालांकि वे शून्य के बजाय एक रिक्त स्ट्रिंग के लिए डिफ़ॉल्ट होते हैं (क्योंकि स्ट्रिंग के स्थिर "लंबाई" फ़ंक्शन 0 पर लौट सकता है यदि अशक्त स्ट्रिंग पर लागू किया गया हो)।
— सुपरकैट

1
# 2 के संबंध में, यह सामान्य रूप से उपयोगी होगा यदि संरचनाएं केवल भराव-शून्य के अलावा एक निर्माणकर्ता को निर्दिष्ट नहीं कर सकती हैं, बल्कि बाइट-फॉर-बाइट-कॉपी के अलावा एक कॉपी कंस्ट्रक्टर भी हो सकती हैं। वास्तव में, मैं वास्तव में एक .net जैसी रूपरेखा देखना चाहता हूं जो यह पहचानने का एक अच्छा काम कर सके कि संस्थाओं में मूल्य या संदर्भ शब्दार्थ हो सकते हैं, और मूल्य-प्रकार के ढेर वस्तुओं को परस्पर, साझा-अपरिवर्तनीय, या अप्रकाशित होने की अनुमति दे सकते हैं। (एक मान रहित मान ऑब्जेक्ट को उत्परिवर्तित किया जा सकता है यदि इसका मोड पहली बार तुलना करने योग्य है, तो उत्परिवर्तनीय के साथ तुलना किया जा सकता है, या इसे साझा किया जा सकता है यदि इसका मोड पहले तुलना है।
— सुपरकैट

1
बहुत बढ़िया अंक! # 1 के लिए, एक प्रकार का सिस्टम एनोटेशन सामान्य समाधान है, लेकिन मैं टी: नया () जैसे प्रकार चर के माध्यम से निर्माण अवरोधों का प्रचार करना पसंद करता हूं। पुन :: # 2, कॉपी बिल्डरों के बारे में अच्छी बात है, लेकिन मैं ऊपर वर्णित लाइनों के साथ और अधिक सामान्य बिल्डरों के साथ खुश रहूंगा। इससे भी बेहतर होगा कि कंस्ट्रक्टरों के रूप में प्रतिष्ठित-विधियों को पूरी तरह से खत्म किया जाए और उन्हें स्थिर तरीके से बनाया जाए। यह सरल और अधिक सामान्य निर्माण पैटर्न की अनुमति देता है, खासकर अगर हम इंटरफेस पर स्थिर तरीकों की अनुमति देते हैं। कंस्ट्रक्टर्स-ऐस-स्टैटिक-मेथड्स + स्टैटिक-मेथड्स-इन-इंटरफेसेस # 1 भी सॉल्व करते हैं।
— naasking

3
# 3: जेनेरिक प्रकार के पैरामीटर के रूप में एक सील वर्ग का उपयोग करने का क्या मतलब है, जैसे फू <टी> जहां टी: स्ट्रिंग? # 11: ठीक है, इसलिए मुझे List<T>एक मिलियन Ts मिल गया है । आप कैसे प्रस्ताव करते हैं कि स्नैपशॉट को कुशलता से लिया जाए? # 21: readonlyकीवर्ड का उपयोग करें .... जबकि यहां कुछ अच्छे सुझाव हैं, वे ज्यादातर सिर्फ यही हैं - सुझाव, डिजाइन दोष नहीं।
— क्वर्टी

2
यह एक बहुत ही दिलचस्प जवाब है, लेकिन मुझे लगता है कि हमें C # 6 सुविधाओं के साथ अपडेट करना चाहिए। उदाहरण: आइटम 19 और 21 को लागू किया गया =)
— एडुआर्डोब्र

72
  • Reset()विधि पर IEnumerator<T>एक गलती थी (इटरेटर ब्लॉकों के लिए, भाषा कल्पना भी मांग है कि यह एक अपवाद फेंकता है)
  • प्रतिबिंब तरीकों कि वापसी सरणियों थे, एरिक के विचार में, एक गलती
  • सरणी सह-अस्तित्व था और एक विषमता बनी हुई थी
    • अद्यतन करें: .NET 4.0 के साथ C # 4.0 ने जेनेरिक इंटरफेस (जैसे IEnumerable<out T>और Func<in T, out TResult>, लेकिन ठोस प्रकार (पसंद नहीं List<T>) को सहसंयोजक / विरोधाभासी समर्थन जोड़ा ।
  • ApplicationException बल्कि पक्ष से बाहर गिर गया - क्या वह गलती थी?
  • सिंक्रनाइज़ किए गए संग्रह - एक अच्छा विचार है, लेकिन वास्तव में उपयोगी नहीं है: आपको आमतौर पर कई कार्यों को सिंक्रनाइज़ करने की आवश्यकता होती है (Contains तब Add) , इसलिए एक संग्रह जो अलग-अलग कार्यों को सिंक्रनाइज़ करता है, वह सब उपयोगी नहीं है
    • अपडेट करें: प्रकार , के साथ , ,System.Collections.ConcurrentTryAddGetOrAddTryRemove , आदि .NET फ्रेमवर्क 4.0 में जोड़ा गया था - हालांकि तरीकों कि एक कारखाने प्रतिनिधि स्वीकार की गारंटी नहीं देते कारखाने केवल प्रति कुंजी एक बार सक्रिय किया जाएगा।
  • अधिक उपयोग using/ lockपैटर्न से बना हो सकता है - शायद उन्हें फिर से प्रयोग करने योग्य (एक्स्टेंसिबल?) सिंटैक्स साझा करने की अनुमति देता है; आप इसे वापस IDisposableकरके और उपयोग करके अनुकरण कर सकते हैंusing , लेकिन यह स्पष्ट हो सकता था
  • इटरेटर ब्लॉक: समय-समय पर (आलस्य के बजाय) तर्कों की जाँच करने का कोई सरल तरीका नहीं। ज़रूर, आप दो जंजीर तरीके लिख सकते हैं, लेकिन यह बदसूरत है
  • सरल अपरिवर्तनीयता अच्छी होगी; C # 4.0 थोड़ा मदद करता है , लेकिन काफी पर्याप्त नहीं है
  • कोई "यह रेफ-टाइप पैरामीटर अशक्त नहीं हो सकता" समर्थन - हालांकि अनुबंध (4.0 में) कुछ हद तक इसके साथ मदद करते हैं। लेकिन सिंटैक्स की तरह Foo(SqlConnection! connection)(कि एक अशक्त-जांच इंजेक्ट /throw ) अच्छा होगा ( int?आदि के विपरीत )
  • जनरेटर के साथ ऑपरेटरों और गैर-डिफ़ॉल्ट बिल्डरों के समर्थन की कमी; C # 4.0 के साथ dynamicइसे थोड़ा हल करता है , या आप इसे सक्षम कर सकते हैं इस तरह से
  • इटरेटर वैरिएबल थोड़ी देर में बाहर घोषित किया जा रहा हैforeach विस्तार , जिसका अर्थ है कि एनॉन-तरीके / लैम्ब्डा एकल चर को कैप्चर करते हैं, बजाय एक प्रति चलना (थ्रेडिंग / एसिंक्स / आदि के साथ दर्दनाक)

IEnumerable! = IEnumerable <object> वास्तव में विषम है
— Rauhotz

2
खैर, IEnumerable बात एक 1.1 हैंगओवर है; आप कम से कम LINQ साथ .Cast <object> () का उपयोग कर सकते हैं,
— मार्क Gravell

8
बीसीएल के लोगों ने कहा कि ApplicationExceptionयह एक गलती थी - जैसे कि उन्हें उम्मीद नहीं थी। उन्होंने यह भी कहा कि System.Exceptionहोना चाहिए था abstract।
— जे बाज़ुज़ी

2
नॉन-न्युलेबल: नॉन-नॉलेबल टी लेने वाली किसी चीज़ के लिए रेगुलर रेफरेंस टाइप T को पास करना एक कंप्लीट एरर होना चाहिए! (जैसे आप int पास नहीं कर सकते? int) दूसरी दिशा से गुजरना ठीक है, ज़ाहिर है।
— जे बाजुज़ी

1
@ जॉन हारोप: IMHO, अपरिवर्तनीय सरणियों के लिए समर्थन होना चाहिए, और केवल-पढ़ने के लिए सरणी संदर्भ के लिए। संभवतः कुछ अन्य ऐरे वेरिएंट के लिए भी (उदाहरण के लिए "रिसिवेबल एरे" (अप्रत्यक्ष संदर्भ), या ऑफ़सेट और बाउंड के साथ एरे संदर्भ)।
— 1

60

TextWriter एक बेस है StreamWriter वर्ग है। WTF?

वह मुझे हमेशा चरम पर ले जाता है।


19
+1 मुझे इसे हर बार देखना होगा। (वधाय का मतलब है कि मैं नया टेक्स्टविटर () नहीं कर सकता)
— निकोलस पियासेकी

1
भगवान का शुक्र है ... मुझे लगा कि यह सिर्फ मैं ही हूं।
— IJ कैनेडी

? यह हमेशा कुछ ऐसा होता है जो पाठ लिखता है, लेकिन केवल स्ट्रीमराइटर एक धारा के लिए ऐसा करता है। बहुत सीधा लगता है।
— जॉन हन्ना

4
StreamWriter नाम इस तथ्य को स्पष्ट नहीं करता है कि यह पाठ स्पष्ट रूप से पर्याप्त IMO लिखता है। यह अलगाव में लगता है जैसे यह सिर्फ बाइट्स लिखेगा और TextWriter शीर्ष पर एक फैंसी कार्यान्वयन होगा जो आपके लिए बाइट्स में (स्ट्रिंग टूराइट) की एपीआई को बाइट्स में बदल देगा। अब अगर इसे StreamTextWriter कहा जाता है तो यकीन है, यह तुरंत स्पष्ट हो जाएगा, लेकिन थोड़ा लंबा :(
— Quibblesome

44

एक छोटा सी # पालतू जानवर - कंस्ट्रक्टर सी ++ / जावा सिंटैक्स का उपयोग करते हैं, कंस्ट्रक्टर वर्ग के समान नाम है।

New() या ctor() बहुत अच्छा होता।

और निश्चित रूप से, कोडरुश जैसे उपकरण वर्गों के नाम बदलने के लिए इसे कम बनाते हैं, लेकिन एक पठनीयता पीओवी, न्यू () से बड़ी स्पष्टता मिलती है।


एर्म, यह कैसे पता चलेगा कि आप एक नया उदाहरण बनाने की कोशिश कर रहे हैं?
— ब्लूराजा - डैनी पफ्लुघोफ्ट

4
@ ब्ल्यूराज: स्कॉट कक्षाओं में निर्माणकर्ताओं के नामकरण की बात कर रहा है। class Foo { new(int j) {i = j} int i; }
— dalle

जबकि मैं 100% सहमत हूं कि ctor () या कंस्ट्रक्टर () बेहतर होता (न कि New--upercase कीवर्ड कन्वेंशन के खिलाफ होते हैं), मैं इसे एक डिज़ाइन दोष कहता हूं। वे मौजूदा सी ++ / जावा डेवलपर्स को आकर्षित करना चाहते थे, और बहुत सारे बेवकूफ पुराने वाक्य रचना सम्मेलनों को उधार लेने से यकीनन उन्हें अपने लक्ष्य तक पहुंचने में मदद मिली।
— क्वर्टी

इस सवाल से संबंधित: stackoverflow.com/questions/32101993/c-sharp-sorted-linkedlist वहाँ कोई रास्ता नहीं है (केवल .NET का उपयोग करके) बस MergeSort, bucketsort या किसी अन्य छँटाई एल्गोरिथ्म के साथ एक LinkedList सॉर्ट करने के लिए, लेकिन linq है कि तरीके धीमी है का उपयोग कर तदर्थ कार्यान्वयन की तुलना में।
— कॉफ़ेवलप्टर

29

मैं नहीं समझता कि आप ऐसा नहीं कर सकते

जहां T: नया (U)

तो आप घोषणा करते हैं कि सामान्य प्रकार T में एक गैर-डिफ़ॉल्ट निर्माता है।

संपादित करें:

मैं यह करना चाहता हूँ:

public class A 
{
    public A(string text) 
    {

    }
}


public class Gen<T> where T : new(string text) 
{

}

एक सामान्य प्रकार घोषित करता है कि आप उस प्रकार की वस्तुओं का उपयोग कैसे करेंगे, अर्थात उनका इंटरफ़ेस। कंस्ट्रक्टर उस इंटरफ़ेस का कार्यान्वयन विवरण है, जो उपभोक्ता की चिंता का विषय नहीं है। जब आपको एक मानकीकृत उदाहरण बनाने की आवश्यकता होती है, तो एक कारखाने का उपयोग करें।
— ब्रायन वत्स

जानकारी के लिए, हालांकि यह संकलन-समय की जाँच नहीं कर सकता है, गैर-डिफ़ॉल्ट निर्माणकर्ताओं (जेनेरिक में) का कुशलतापूर्वक उपयोग करने के लिए, यानी Activator.CreateInstance या प्रतिबिंब के बिना MiscUtil में कुछ कोड है।
— मार्क ग्रेवेल

क्योंकि यह कोई मतलब नहीं है और कुछ उपयोगों पर भ्रमित है। फिर भी अपरिवर्तनीय वस्तुओं के साथ काम करने पर यह उपयोगी हो सकता है।
— पॉप कैटलिन

7
सामान्य तौर पर, सदस्य बाधाओं की कमी कष्टप्रद है, हाँ।
— माइकलजी

3
आमीन, मैं हमेशा से यही चाहता हूँ
— स्टीव

20

मैं वास्तव में आश्चर्यचकित हूं कि मैं यह उल्लेख करने वाला पहला व्यक्ति हूं:

ADO.NET टाइप किए गए डेटा सेट अशक्त स्तंभों को अशक्त प्रकारों के गुणों के रूप में उजागर नहीं करते हैं। आपको यह लिखने में सक्षम होना चाहिए:

int? i = myRec.Field;
myRec.Field = null;

इसके बजाय, आपको यह लिखना होगा, जो सिर्फ बेवकूफ है:

int? i = (int?)myRec.IsFieldNull() ? (int?)null : myRec.Field;
myRec.SetFieldNull();

यह .NET 2.0 में कष्टप्रद था, और यह अब और भी अधिक कष्टप्रद है कि आपको अपने अच्छे नीम LINQ प्रश्नों में उपरोक्त की तरह गुड़-पकौड़ी का उपयोग करना होगा।

यह भी कष्टप्रद है कि उत्पन्न Add<TableName>Rowविधि इसी प्रकार अशक्त प्रकार की धारणा के प्रति असंवेदनशील है। उत्पन्न होने के बाद से सभी और अधिकTableAdapter विधियों के ।

.NET में बहुत कुछ नहीं है जो मुझे महसूस करता है कि देव टीम ने कहा "ठीक है, लड़कों, हम काफी करीब हैं - इसे शिप करें!" लेकिन यह सुनिश्चित करता है।


मैं तहे दिल से सहमत हूँ! हर बार मुझे इसका उपयोग करना पड़ता है (जो कि अक्सर होता है)। अरे! +1
— आंखों की रोशनी

2
कम से कम वे एक नया DataSetV2 वर्ग (बुरा नाम - सिर्फ तर्क के लिए) के साथ आ सकते हैं, जो कि DBNull के बजाय अशक्त मान प्रकार का उपयोग करते थे।
— क्रिश्चियन हैटर

आइए एक विशेष मूल्य की आवश्यकता की अनुपस्थिति को मत भूलना DBNull.Value, जब nullखुद NULL का प्रतिनिधित्व करने के लिए पूरी तरह से पर्याप्त होगा। सौभाग्य से LINQ-to-SQL सिर्फ नल के लिए नल का उपयोग करता है।
— क्वर्टी

असल में वह असावधानी वह चट्टान है, जिस पर पूरी बेतुकी इमारत का निर्माण किया गया था।
— रॉबर्ट रॉसनी

20
  1. मैं स्ट्रीम, StringWriter, StringReader, TextReader, TextWriter वर्गों का बड़ा प्रशंसक नहीं हूं ... यह सहज नहीं है कि क्या है।
  2. IEnumerable.Reset पुनरावृत्तियों के लिए एक अपवाद फेंक। मेरे पास कुछ थर्ड पार्टी कंपोनेंट्स हैं जो डेटाबाउंड के दौरान हमेशा रीसेट कहते हैं, मुझे इनका उपयोग करने के लिए पहले एक सूची में डालना होगा।
  3. Xml Serializer में ID Analytics तत्वों को क्रमांकित होना चाहिए
  4. मैं पूरी तरह से HttpWebRequest और FTP API के बारे में भूल गया कि मेरे दर्द में क्या है .... (टिप्पणी निकोलस के लिए धन्यवाद मुझे यह याद दिलाने के लिए :-)

संपादित करें
5. मेरा एक और झुंझलाहट है कि कैसे System.Reflection.BindingFlags, आपके उपयोग करने की विधि के आधार पर अलग-अलग उपयोग करता है। FindFields में उदाहरण के लिए CreateInstance या SetField का क्या अर्थ है? यह एक ऐसा मामला है जहां उन्होंने इस गणना के पीछे के अर्थ को ओवरलोड किया है जो भ्रामक है।


1
+1 मुझे हर एक समय में किसी भी XmlTextWriter, TextWriter इत्यादि को देखना होगा। HttpWebRequest / Response सामान के साथ समान। वहाँ पूरी तरह से अनजाने एपीआई।
— निकोलस पियासेकी

+ 1-1 = 0: XmlTextWriter इत्यादि, मैं नाम से जो कुछ भी है, उसका सही-सही पता लगाना असंभव मानता हूँ। HttpWebRequest मैं सहमत नहीं हूँ मैं इसे काफी सहज ज्ञान युक्त लगता हूँ।
— एंथनीवजोन

प्रत्येक अपने स्वयं को, मुझे लगता है। मुझे लगता है कि मैं एफ़टीपी के साथ उच्च स्तर की अमूर्तता की उम्मीद करता हूं तो उनके पास क्या है।
— जोशबर्के

15

मुझे नहीं पता कि मैं यह कहना चाहूंगा कि यह एक डिजाइन दोष है, लेकिन यह वास्तव में अच्छा होगा यदि आप उसी तरह से लंबोदर अभिव्यक्ति का अनुमान लगा सकते हैं, जैसा कि आप वीबी में कर सकते हैं:

वीबी:

Dim a = Function(x) x * (x - 1)

सी#

यह अच्छा होगा यदि यह कर सके:

var a = x => x * (x - 1);

ऐसा करने के बजाय:

Func<int, int> a = x => x * (x - 1);

मुझे लगता है कि यह बहुत लंबा नहीं है, लेकिन कोड गोल्फ में हर चरित्र बहुत मायने रखता है! क्या वे उस समय को ध्यान में नहीं रखते हैं जब वे इन प्रोग्रामिंग भाषाओं को डिज़ाइन करते हैं? :)


3
Microsoft को भाषा को डिज़ाइन करते समय कोड गोल्फ को ध्यान में रखना चाहिए?
— jrcs3

3
@ रे बर्न्स: यह वीबी में कैसे पता चलता है? VB इसका समर्थन करता है, तो क्या अंतर है?
— बेनलाबस्टर 23

3
@RayBurns प्रकार का निष्कर्ष? मैं 1989 से इसका उपयोग कर रहा हूं।
— RD1

3
लमदास C # में होम्योनिक हैं। टुकड़ा (int x) => x * (x -1);मतलब हो सकता है Func<int, int>या इसका मतलब हो सकता हैExpression<Func<int, int>>
— स्कॉट विंस्टीन

3
@BenAlabaster: VB देर से बाउंड अंकगणितीय ऑपरेटरों का समर्थन करता है। C # उन्हें संकलन समय पर हल करना होगा। यह भाषा का अंतर है। उदाहरण के लिए वीबी दो वस्तुओं को एक साथ जोड़ सकता है। C # नहीं कर सकता क्योंकि +इसके लिए परिभाषित नहीं किया गया है object।
— पुनरावर्ती

14
  1. System.Object वर्ग:

    • समान और GetHashCode - सभी कक्षाएं तुलनीय या धोने योग्य नहीं हैं, उन्हें एक इंटरफ़ेस में स्थानांतरित किया जाना चाहिए। IEquitable या IComparable (या समान) दिमाग में आता है।

    • ToString - सभी वर्गों को एक स्ट्रिंग में नहीं बदला जा सकता है, इसे एक इंटरफ़ेस में स्थानांतरित किया जाना चाहिए। माननीय (या समान) दिमाग में आता है।

  2. ICollection.SyncRoot संपत्ति:

    • खराब डिजाइन को बढ़ावा देता है, एक बाहरी ताला लगभग हमेशा अधिक उपयोगी होता है।
  3. शुरुआत से ही जेनरिक होनी चाहिए:

    • System.Collections नाम स्थान और अधिक या कम अप्रचलित वर्गों और इंटरफेस की एक बहुत कुछ शामिल।

1
1. वे तरीके इतने सामान्य हैं कि यह तय किया गया कि ऑडबॉल के मामले ठीक थे, क्या इससे कोई फर्क पड़ता है कि कोई आपकी कक्षा में ऑब्जेक्ट.क्वाल्स कह सकता है? यह ज्ञात है कि एक कार्यान्वयन हो सकता है या नहीं भी हो सकता है, और आवश्यकता हो सकती है: 99% वर्गों पर IEquitable, IFormattable विषम है।
— ग्वेंटे

1
उदाहरण के लिए उपयोगकर्ता-परिभाषित वस्तुओं में कोड को स्पष्ट रूप से जोड़ने के बिना, उदाहरण के लिए, डिफ़ॉल्ट संदर्भ समानता का उपयोग करके, उपयोगकर्ता-परिभाषित वस्तुओं के साथ एक शब्दकोश बनाने में सक्षम होना उपयोगी है। मुझे लगता है कि अंतिम रूप से एक बहुत बड़ा अपशिष्ट होगा (एक बेहतर विकल्प वस्तुओं के लिए होता है जिसे अंतिम रूप देने की आवश्यकता होगी iFinalizable और स्पष्ट रूप से अंतिम रूप से खुद को पंजीकृत करने के लिए)। OTOH, iDis प्रयोज्य के लिए अधिक अंतर्निहित समर्थन होना चाहिए, जिसमें कॉलिंग डिस्पोज भी शामिल है यदि एक कंस्ट्रक्टर एक अपवाद फेंकता है।
— सुपरकाट

1
@ सुपरकैट: सभी की जरूरत है जो EqualityComparer<T>.Defaultसही तरीके से अपडेट हो। फिर दोनों var dict = new Dictionary<object, string>(EqualityComparer<object>.Default)और var dict = new Dictionary<object, string>()संदर्भ तुलना / समानता का प्रयोग करेंगे।
— dalle

1
@ सुपरकैट: आप जो वर्णन करते हैं, वही EqualityComparer<T>.Defaultकरता है। हर लुकअप पर जांच की जरूरत नहीं है। तुलना करने वाला Dictionaryउदाहरण के लिए एक संपत्ति है , और प्रत्येक Dictionaryजानता है कि वह किसका उपयोग कर रहा है।
— dalle

1
@supercat: किसी शब्दकोश में सबसे सामान्य प्रकार (यानी सामान्य आधार वर्ग) को कुंजी के रूप में उपयोग किया जाना चाहिए, एक ही शब्दकोश में स्ट्रिंग्स और डेटटाइम दोनों का उपयोग करने से संदर्भ-तुलना का उपयोग करने तक कोई भी सार नहीं होगा, जब तक कि उपयोगकर्ता द्वारा परिभाषित तुलना साबित नहीं होती है। है। याद रखें कि इस विषय का नाम "C # (.NET) डिज़ाइन फ़्लास" है।
— dalle

12

मुझे चिढ़ाने वाली चीजों में एक है Predicate<T> != Func<T, bool>विरोधाभास। वे दोनों प्रकार के प्रतिनिधि हैं T -> boolऔर अभी तक वे असाइनमेंट संगत नहीं हैं।


Delegate.Create और रूपांतरण करने के लिए कुछ कास्टिंग का उपयोग करने के लिए एक चाल है, लेकिन कम से कम एक स्पष्ट कास्ट करने में सक्षम होना अच्छा होगा (मैं हालांकि निहित के लिए समर्थन की कमी को समझ सकता हूं)
— Guvante

सामान्य रूप से प्रतिनिधियों का डिजाइन त्रुटिपूर्ण है; उदाहरण के लिए कमजोर घटनाओं की कमी (ग्राहक से विशेष प्रयास के बिना स्रोत-पक्ष की कमजोर घटनाओं को लागू करना केवल प्रतिबिंब और प्रतिबिंब प्रतिबिंब का एक गुच्छा के साथ किया जा सकता है, codeproject.com/Articles/29922/Weak-Events-in-C देखें ), और अक्षमता जो आवश्यकता से आती है कि प्रतिनिधियों को संदर्भ प्रकार होना चाहिए (प्रतिनिधियों का तेजी से विकास हुआ होगा, और कई मामलों में 1/3 का उपयोग करना होगा, यदि वे मूल्य प्रकार थे - तो वे बस एक जोड़ी होंगे पॉइंटर्स जिसे आप स्टैक पर पास कर सकते हैं।)
— क्वाटर्ली

11

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


दौड़ने से पहले आपको अपने कार्यक्रम को एनजीईएन करने में सक्षम होना चाहिए।
— ओट्टोवियो डेसिओ

रनटाइम की निर्भरता को हटाने के समान नहीं। आप केवल अपने कोड पर पहले JIT रन बचाते हैं।
— एड।


क्या ऐसा कोई उपकरण नहीं है जो ऐसा करता हो? यह आपके exe में रूपरेखा को एम्बेड करेगा ताकि आपको इसे तैनात न करना पड़े। मैं इसका नाम नहीं
— बता

2
क्या Xenocode के Postbuild ऐसा नहीं करते हैं? यह अच्छा होगा यदि विज़ुअल स्टूडियो के पास ऐसा करने का तरीका हो ...
— बेनलास्टर

11

हम अधिकार के बारे में बहुत कुछ जानते हैं OO तकनीकों के । Decoupling, अनुबंध द्वारा प्रोग्रामिंग, अनुचित विरासत से बचने, अपवादों का उचित उपयोग, खुला / बंद प्रिंसिपल, लिस्कोव प्रतिस्थापन, और इसी तरह। अभी तक, .Net फ्रेमवर्क सर्वोत्तम प्रथाओं को नियोजित नहीं करते हैं।

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

यदि एमएस ने इस पर ध्यान दिया, तो सॉफ्टवेयर इंजीनियरिंग की दुनिया इस दशक में गुणवत्ता, स्थिरता और स्केलेबिलिटी के मामले में बड़ी छलांग लगा सकती है, लेकिन अफसोस यह फिर से होने लगा है।


4
ऑन-टेंट रेंट के लिए +1; मैं हर वर्ग को उपवर्ग में शामिल करने में असमर्थता जोड़ूंगा, मूलभूत वर्गों के लिए इंटरफेस की कमी, और कई वर्षों के बाद भी फ्रेमवर्क बग को ठीक करने की अनिच्छा
— स्टीवन ए लोवे

1
यदि हम पीछा करते हैं, तो क्या हम कह रहे हैं कि .नेट फ्रेमवर्क सिर्फ इतना बुरा है कि इसे निपटाना कठिन है कि कौन सा दोष सबसे खराब है? मैं एक वेंट के बाद बेहतर महसूस करता हूं और अपवोट की सराहना करता हूं क्योंकि मुझे एमएस फैन लड़कों द्वारा चिल्लाए जाने की उम्मीद थी।
— डैनियल पाउल

मैंने किसी भी तरह से मतदान नहीं किया है, और वैसे भी मैं डाउन-वोट जारी करने के लिए बहुत अनिच्छुक हूं, लेकिन मैं यह पता लगाने की कोशिश कर रहा हूं कि मुझे बस क्यों परवाह नहीं है।
— माइक डनलैवी

2
मुझे लगता है कि आप कह रहे हैं "यह उतना अच्छा नहीं है जितना यह हो सकता है" जो कि एक गैर-उत्तर है। कुछ भी पूर्ण नहीं है। विवरण प्रदान करें।
— जकॉल्म

3
नहीं, मैं कह रहा हूं कि ऐसे कई उदाहरण हैं जहां डिजाइन स्पष्ट रूप से त्रुटिपूर्ण है, तो जब आपको लगता है कि वे इसे सही कर लेते हैं, तब भी वे गलत हैं। उदाहरण के लिए, MSDN फ़ोरम में मेरी पोस्ट यहाँ: social.msdn.microsoft.com/forums/en-US/wpf/thread/…
— डैनियल

11

मुझे C # स्विच स्टेटमेंट पसंद नहीं है।

मैं कुछ इस तरह से चाहूंगा

switch (a) {
  1    : do_something;
  2    : do_something_else;
  3,4  : do_something_different;
  else : do_something_weird; 
}

तो कोई और अधिक विराम (आसान भूलना) और अल्पविराम-अलग-अलग मूल्यों की संभावना।


वास्तव में मुझे लगता है कि यह और भी बेहतर होगा अगर इसे या तो एक ही कथन की आवश्यकता होगी या घुंघराले कोष्ठक में एक ब्लॉक - जैसे कि C # में सब कुछ होगा। के माध्यम से गिरने की क्षमता के बिना, वर्तमान ब्रेक सिंटैक्स थोड़ा डोडी है और यह स्कोप तक सीमित नहीं करता है। (AFAIK, यह हो सकता है, मुझे नहीं पता)
— तमस Czinege

मुझे समझ नहीं आ रहा है कि आपका क्या मतलब है। यहां अपना 'आदर्श' स्विच स्टेटमेंट पोस्ट करें। मैं नहीं चाहता, लेकिन अल्पविराम से अलग हुए मूल्यों के माध्यम से।
— तुनस्टेल

8
वैसे, मैं ओपी से सहमत हूं। switchसभी भाषाओं में मौलिक रूप से टूट गया है जो सी के जानबूझकर अपंग संस्करण (गति के लिए अनुकूलित!) का अनुकरण करते हैं। VB का किराया बहुत बेहतर है, लेकिन पैटर्न मिलान (हास्केल, एफ #…) वाली भाषाओं के पीछे अभी भी प्रकाश-वर्ष है।
— कोनराड रुडोल्फ

1
tuinostel: स्विच की तरह कुछ (ए) {केस 1 {do_something; } केस 2 {do_something_else; }} - अर्थात, ब्रेक स्टेटमेंट से छुटकारा पाने और प्रत्येक मामले के लिए उचित कोड ब्लॉक की आवश्यकता है
— तमस Czinege

2
ब्रेक होना सामान्य रूप से एक गलती की तरह लगता है, क्या यह इसे फेंकने के लिए एक संकलन त्रुटि नहीं है? ऐसा लगता है कि केवल C से C # में परिवर्तन को आसान बनाने के लिए # (उर्फ शिक्षण
— देवता हैं

10

C # में ईवेंट, जहां आपको श्रोताओं के लिए स्पष्ट रूप से जांच करनी है। घटनाओं के साथ बात नहीं थी, जो भी वहाँ हो प्रसारण करने के लिए? भले ही कोई भी क्यों न हो?


1
यह कष्टप्रद है कि जब आप चाहते हैं तो इसके लिए चीनी नहीं है, मैं देखता हूं कि वे इसे कठिन क्यों करते हैं, यह आवश्यक नहीं होने पर घटना के तर्कों को तत्काल नहीं करने के लिए प्रोत्साहित करता है
— ShuggyCoUk

हम्म। मुझे या तो समझ में नहीं आता या असहमत, या दोनों :-)। मैं यह नहीं कह सकता कि मैंने कभी भी किसी भी चीज को तुरंत हतोत्साहित महसूस किया। यह मेरे लिए समय से पहले अनुकूलन की तरह बदबू आ रही है।
— थॉमस आइड

आंशिक तरीके कुछ मामलों में एक व्यवहार्य विकल्प हैं।
— रॉबर्ट हार्वे

इसके अलावा सभी युग्मन के कारण ... MS में CAB है जो इन दोनों समस्याओं को ठीक करता है, लेकिन CAB की सी # में सीमाओं के कारण स्वयं की बहुत सी समस्याएं हैं (उदाहरण के लिए घटना-विषयों के बजाय enums के बजाय स्ट्रिंग्स) - क्यों न केवल शिथिल बनाएं। - भाषा की घटनाओं का हिस्सा ?
— ब्लूराजा - डैनी पफ्लुघोफ्ट

9

भयंकर (और ज्यादातर लोगों के लिए काफी अदृश्य) हे (एन ^ 2) नेस्ट / पुनरावर्ती के व्यवहार iterators ।

मुझे इस बात का बहुत मलाल है कि वे इसके बारे में जानते हैं, जानते हैं कि इसे कैसे ठीक करना है लेकिन इसे योग्यता के समावेश के लिए पर्याप्त प्राथमिकता के रूप में नहीं देखा जाता है।

मैं हर समय संरचनाओं की तरह पेड़ के साथ काम करता हूं और सही तरीके से अन्यथा स्मार्ट लोगों के कोड को सही करना पड़ता है जब वे अनजाने में इस तरह से अत्यधिक महंगे ऑपरेशन पेश करते हैं।

"यील्ड फॉरचेक" की सुंदरता यह है कि सरल, आसान सिंटैक्स सही, कलाकार कोड को प्रोत्साहित करता है " सफलता का पिटारा "है, जो मुझे लगता है कि उन्हें प्लेटफ़ॉर्म की दीर्घकालिक सफलता के लिए नई सुविधाओं को जोड़ने से पहले आकांक्षा करनी चाहिए।


यह विशेष रूप से त्रुटिपूर्ण है, क्योंकि यह ओ व्यवहार ans की सहज अपेक्षाओं के खिलाफ जाता है इसलिए बहुत से लोगों को फंसा देगा
— oefe

7

कुछ वर्ग इंटरफेस को लागू करते हैं, लेकिन वे उस इंटरफ़ेस के कई तरीकों को लागू नहीं करते हैं, उदाहरण के लिए ऐरे को लागू करता है लेकिन 9 में से 4 तरीके NotSupportedException http://msdn.microsoft.com/en-us/library/system/array_members फेंक देते हैं .aspx


ठीक है, आप एक ऐरे में तत्वों की संख्या को बदल नहीं सकते हैं, इसलिए इसमें कुछ भी नहीं है कि ऐड, क्लियर, इंसर्ट और रिमूव (एट) कर सकते हैं, लेकिन NotSupported को फेंक सकते हैं ... वास्तव में, मुझे उम्मीद है कि IList के किसी भी कार्यान्वयन के लिए जो सही है IsFixedSize उन पर फेंक देगा।
— सीबी

@CB पार्टी के लिए थोड़ा देर से मुझे लगता है :) लेकिन अगर ऐरे "IList" को संतुष्ट नहीं कर सकता, तो इसे वैसे भी क्यों लागू करें? यह ठोस सिद्धांत में एल का उल्लंघन है।
— विंगर सेंडोन

7

स्थैतिक सदस्य और इंटरफेस में नेस्टेड प्रकार।

एक अंतरफलक सदस्य (एक प्रकार का एक पैरामीटर है कि इंटरफ़ेस के लिए विशिष्ट है है जब यह विशेष रूप से उपयोगी है जैसे एक enum)। इंटरफ़ेस प्रकार में एनम प्रकार को घोंसला बनाना अच्छा होगा।


1
Isn 'यह आपके अन्य सुझाव के समान है?
— RCIX 30:09

1
नहीं, यह एक C # भाषा के बारे में है और दूसरा फ्रेमवर्क के बारे में है। हर कोई भेद की परवाह नहीं करता है, इसलिए मुझे कहना चाहिए कि यह एक है जो अनुमति दी गई है, और दूसरा वह है जो प्रदान किया गया है।
— जे बाजुज़ी

6

घटनाओं की बहुत खतरनाक डिफ़ॉल्ट प्रकृति। तथ्य यह है कि आप किसी ईवेंट को कॉल कर सकते हैं और ग्राहकों को हटाए जाने के कारण असंगत स्थिति में हो सकते हैं। विषय पर अधिक पढ़ने के लिए जॉन स्कीट और एरिक लिपर्ट के उत्कृष्ट लेख देखें ।


अगर घटनाओं को डिफ़ॉल्ट रूप से थ्रेड-सुरक्षित नहीं किया गया है तो मुझे कोई आपत्ति नहीं होगी (यह एकल-थ्रेडेड कोड में प्रदर्शन बढ़ा सकता है); जो मूर्खतापूर्ण है वह यह है कि डिफ़ॉल्ट रूप से जोड़ना / हटाना सुरक्षित है, लेकिन यह कि किसी घटना को आग लगाने का प्राकृतिक तरीका असुरक्षित है, और इसे आसानी से सुरक्षित बनाने के लिए कोई सुविधा नहीं है।
— 21

@Qwertie: क्या sillier है कि काफी समय के लिए, जोड़ने / हटाने लॉकिंग का उपयोग करेगा और अभी भी थ्रेड-सुरक्षित नहीं होगा।
— सुपरकैट

6
  • null हर जगह।

  • const कहीं भी नहीं।

  • एपीआई असंगत हैं, उदाहरण के लिए एक सरणी रिटर्न म्यूट कर रहे हैं, voidलेकिन StringBufferरिटर्न एक ही उत्परिवर्तित करने के लिए संलग्न StringBuffer।

  • संग्रह इंटरफेस अपरिवर्तनीय डेटा संरचनाओं के साथ असंगत हैं, उदाहरण के लिए Add में System.Collections.Generic.IList<_>एक परिणाम नहीं लौटा सकता।

  • कोई संरचनात्मक टाइपिंग नहीं है ताकि आप लिखें System.Windows.Media.Effects.SamplingMode.Bilinear सिर्फ बजाय Bilinear।

  • परिवर्तनशील IEnumeratorजब यह अपरिवर्तनीय होना चाहिए तब कक्षाओं द्वारा लागू किया जाने वाला इंटरफ़ेस struct।

  • समानता और तुलना एक मेस हैं: आप मिल गया है System.IComparableऔर Equalsलेकिन फिर आप भी मिल गया है System.IComparable<_>, System.IEquatable, System.Collections.IComparer, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.Collections.Generic.IComparerऔर System.Collections.Generic.IEqualityComparer।

  • ट्यूपल्स को संरचित होना चाहिए लेकिन संरचनाएं अनावश्यक रूप से पूंछ कॉल उन्मूलन को रोकती हैं, इसलिए सबसे आम और मौलिक डेटा प्रकारों में से एक अनावश्यक रूप से आवंटित करेगा और स्केलेबल समानता को नष्ट करेगा।


सीएलआर में कोई स्ट्रक्चरल टाइपिंग नहीं है, लेकिन आपको लगता है कि टाइपिंग इनफैक्शन के साथ या "प्रतीकों" के रूप में जाना जाने वाला रूबी फीचर के साथ स्ट्रक्चरल टाइपिंग मिली है। यदि सीएलआर फंक <int, बूल> और प्रेडिकेट <int> को एक ही प्रकार, या कम से कम अनुमानित रूप से परिवर्तनीय माना जाता है, तो संरचनात्मक टाइपिंग होगी।
— 22

तुलना की बात करें, तो तुलना मत भूलना <T>!
— 22

@Qwertie मैं OCaml में पॉलिमॉर्फिक वेरिएंट जैसी प्रोग्रामिंग लैंग्वेज फीचर्स का जिक्र कर रहा था। OCaml की LablGL लाइब्रेरी में ग्राफिक्स के संदर्भ में संरचनात्मक टाइपिंग के कई दिलचस्प उदाहरण उपयोगी हैं। प्रकार के अनुमान से कोई लेना-देना नहीं है और केवल प्रतीकों से संबंधित है।
— जद

1
कोई अपरिवर्तनीय संरचना का उपयोग कैसे करेगा IEnumerator?
— सुपरकैट

5

0 चांदनी को एनम

एनम की ख़ासियत: http://blogs.msdn.com/abhinaba/archive/2007/01/09/more-peculiarites-of-enum.aspx

जैसा कि इस अच्छे उदाहरण से स्पष्ट होता है: http://plus.kaist.ac.kr/~shoh/postgresql/Npgsql/apidocs/Npgsql.NpgsqlParameterColmetion.Add_overload_3.html

मेरा सुझाव है, "@" साइन को अच्छे उपयोग के लिए रखें:

के बजाय:

अगर ((myVar और MyEnumName.ColorRed)! = 0)

इसे इस्तेमाल करो:

अगर ((myVar और MyEnumName.ColorRed)! = @ 0)


1
+1 enum कुछ चीजों में से एक है जो जावा ने ठीक किया था जबकि C # नहीं
— BlueRaja - Danny Pflughoeft

5

पहले से ही दूसरों द्वारा किए गए अच्छे बिंदुओं की लंबी सूची में जोड़ने के लिए:

  • DateTime.Now == DateTime.Now ज्यादातर मामलों में, लेकिन सभी मामलों में नहीं।

  • Stringजो अपरिवर्तनीय है उसके पास निर्माण और हेरफेर के लिए विकल्पों का एक गुच्छा है, लेकिन StringBuilder(जो कि परिवर्तनशील है) नहीं करता है।

  • Monitor.Enterऔर Monitor.Exitउदाहरण के तरीके होने चाहिए थे, इसलिए लॉकिंग के लिए एक विशिष्ट वस्तु को नया करने के बजाय, आप उस पर नया Monitorऔर लॉक कर सकते थे ।

  • विध्वंसक का नाम कभी भी विध्वंसक नहीं होना चाहिए था। ECMA कल्पना उन्हें अंतिम रूप से बुलाती है, जो C ++ भीड़ के लिए बहुत कम भ्रमित है, लेकिन भाषा विनिर्देश अभी भी उन्हें अवरोधक के रूप में संदर्भित करता है।


3
DateTime.Nowएक दुनिया की सबसे स्पष्ट दौड़ शर्त है, लेकिन +1 आराम के लिए है
— BlueRaja - डैनी Pflughoeft

यह इतना नहीं है कि यह एक दौड़ की स्थिति है, लेकिन तथ्य यह है कि उन्होंने इसे एक संपत्ति बना दिया। गुण बिल्कुल खेतों की तरह दिखते हैं, इसलिए यह आश्चर्यजनक व्यवहार आईएमओ है।
— ब्रायन रासमुसेन

4
@ ब्रायन रासमुसेन: DateTime.Now काफी अच्छी तरह से एक संपत्ति है, क्योंकि इसे इसे पढ़ने से नहीं, बल्कि बाहरी कारकों द्वारा बदला जाता है। यदि कोई SomeForm.Width की तरह एक संपत्ति पढ़ता है, और फिर - उपयोगकर्ता द्वारा आकार बदलने के बाद - एक इसे फिर से पढ़ता है, तो दूसरे रीड पर मूल्य अलग होगा। हालांकि यह संभव है कि पहला DateTime.Now निष्पादित करने में काफी लंबा समय ले सकता है कि यह दूसरे द्वारा पढ़े गए मूल्य को प्रभावित करेगा, इस तरह का प्रभाव किसी भी अन्य फ़ंक्शन से अलग नहीं होगा जिसके निष्पादन में समान समय लगा।
— सुपरकाट

4

जिस तरह से हम गुणों का उपयोग करते हैं वह मुझे कभी-कभी परेशान करता है। मैं उन्हें जावा के getFoo () और setFoo () विधियों के बराबर के रूप में सोचना पसंद करता हूं। लेकिन वे नहीं हैं।

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

उस अंत तक, मैं हमेशा कामना करता हूं (यह ज्यादातर यहां जोर से सोच रहा है, मैं बस इस तरह की कामना करता हूं कि मैं कुछ ऐसा कर सकूं) कि मैं किसी तरह संपत्ति के सिंटैक्स का विस्तार कर सकूं। कुछ इस तरह की कल्पना करें:


private string password;

public string Password
{
    // Called when being set by a deserializer or a persistence
    // framework
    deserialize
    {
       // I could put some backward-compat hacks in here. Like
       // weak passwords are grandfathered in without blowing up
       this.password = value;
    }
    get
    {
       if (Thread.CurrentPrincipal.IsInRole("Administrator"))
       {
           return this.password;
       }
       else
       {
           throw new PermissionException();
       }
    }
    set
    {
       if (MeetsPasswordRequirements(value))
       {
           throw new BlahException();
       }
       this.password = value;
    }
    serialize
    {
        return this.password;
    }
}

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


3
मेरा मानना ​​है कि वे उस तरह के काम करने के लिए ISerializable इंटरफ़ेस और अंतर्निहित निर्माता प्रदान करते हैं, उर्फ़ जब आप चाहते हैं कि धारावाहिक को बस गुणों को कॉल न करें। जबकि थोड़ा और काम, ऐसा लगता है कि आप पहले से ही अपने काम के साथ काम कर रहे हैं।
— ग्वेंटे

4

एक्सटेंशन के तरीके अच्छे हैं, लेकिन वे उन समस्याओं को हल करने के लिए एक बदसूरत तरीका है, जो वास्तविक मिक्सिंस के साथ क्लीनर को हल कर सकते थे (रूबी को देखने के लिए कि मैं किस बारे में बात कर रहा हूं), मिक्सिंस के विषय पर। उन्हें भाषा से जोड़ने का एक अच्छा तरीका यह होगा कि आनुवांशिकता को वंशानुक्रम के लिए इस्तेमाल किया जा सके। यह आपको एक अच्छी वस्तु उन्मुख तरीके से मौजूदा कक्षाओं का विस्तार करने की अनुमति देता है:

public class MyMixin<T> : T
{
    // etc...
}

उदाहरण के लिए एक स्ट्रिंग का विस्तार करने के लिए इसका उपयोग इस तरह किया जा सकता है:

var newMixin = new MyMixin<string>();

यह विस्तार विधियों की तुलना में कहीं अधिक शक्तिशाली है क्योंकि यह आपको तरीकों को ओवरराइड करने की अनुमति देता है, उदाहरण के लिए उन्हें लपेटने की अनुमति देता है ताकि भाषा के अंदर एओपी जैसी कार्यक्षमता हो।

शेख़ी के लिए खेद :-)


5
दिलचस्प है, लेकिन मैं विस्तार के तरीकों को पसंद करता हूं। अगर मुझे एक लाइब्रेरी मिलती है जिसमें स्ट्रिंग्स के लिए विस्तार विधियों का एक गुच्छा होता है, तो मैं नया सामान प्राप्त करने के लिए सभी स्ट्रिंग संदर्भों को MyMixin <string> में बदलना नहीं चाहता। यह एक प्रकार का मामूली है, निश्चित है, लेकिन तरीकों का पारदर्शी जोड़ वही है जो विस्तार विधियों को इतना अच्छा बनाता है।
— RCIX 30:09

BTW क्या आप जानते हैं कि यह पहले से ही काम करता है?
— RCIX 30:09

2
मैं नहीं देखता कि LINQ इस तरह से कैसे काम कर सकता है
— BlueRaja - Danny Pflughoeft

2
@ क्रिक्स: मिक्सिन ध्वनि वे जिस तरह से मैंने सोचा है कि विस्तार के तरीकों को काम करना चाहिए। विस्तार के तरीकों को अंतर्निहित करने में समस्या यह है कि इसका मतलब है कि वास्तविक वर्ग के सदस्यों को विस्तार विधियों पर प्राथमिकता देने की आवश्यकता है। यदि एक विस्तार विधि Graphics.DrawParallelogram (पेन पी, प्वाइंट v1, प्वाइंट v2, प्वाइंट v3) को परिभाषित किया गया है और बाद में एक DrawParallelogram फ़ंक्शन सिस्टम में जोड़ा जाता है। गैस्ट्रिक्स जो एक अलग क्रम में बिंदुओं का उपयोग करता है, एक्सटेंशन विधि का उपयोग करके कोड बिना टूट जाएगा चेतावनी। BTW, क्या विस्तार विधियों के लिए दो डॉट्स का उपयोग करने में कोई समस्या रही होगी (उदाहरण के लिए ऑब्जेक्ट..मिथोड ()?)
— सुपरकैट

3

Microsoft फ्रेमवर्क में स्पष्ट बग्स को ठीक नहीं करेगा और हुक प्रदान नहीं करेगा ताकि अंतिम उपयोगकर्ता उन्हें ठीक कर सकें।

इसके अलावा, रनटाइम के दौरान बाइनरी-पैच .NET निष्पादक का कोई तरीका नहीं है और नेट लाइब्रेरीज़ (लोड कॉल को इंटरसेप्ट करने के लिए) को बाइनरी पैच किए बिना .NET फ्रेमवर्क लाइब्रेरी के निजी संस्करणों को निर्दिष्ट करने का कोई तरीका नहीं है, और ILDASM पुनर्वितरण योग्य नहीं है - मैं इसे स्वचालित नहीं कर सकता वैसे भी पैच।


1
क्या स्पष्ट रूपरेखा कीड़े मतलब है?
— रॉबर्ट रोसनी

1
# 1 स्क्रॉल करने योग्य नियंत्रण के आंशिक रूप से दिखाई देने वाले बच्चे के नियंत्रण पर क्लिक करें। माउसडाउन घटना को प्राप्त करने से पहले नियंत्रण को दृश्य में स्थानांतरित कर दिया जाता है, जिससे नियंत्रण पर क्लिक उम्मीद से कहीं अधिक हो जाता है। यह पेड़ के विचारों पर बदतर है, जहां यह एक ड्रैग ऑपरेशन को भी चलाता है।
— जोशुआ


3
  • अशक्त चर पर एक विस्तार विधि को लागू करने में सक्षम होना चाहिए

    ऑब्जेक्ट ए = अशक्त; a.MyExtMethod (); // यह कॉल करने योग्य है, मान लें कि उसने कहीं MyExtMethod को परिभाषित किया है

    यह आसान हो सकता है लेकिन यह अशक्त संदर्भ अपवाद विषयों पर अस्पष्ट है।

  • एक नामकरण 'दोष'। System.configuration.dll में "कॉन्फ़िगरेशन" का 'C' कैपिटल में होना चाहिए।

  • उपवाद सम्भालना। अपवाद को जावा में जबरन पकड़ा या फेंक दिया जाना चाहिए, संकलनकर्ता को संकलन समय पर इसकी जांच करनी चाहिए। उपयोगकर्ताओं को लक्ष्य आह्वान के भीतर अपवाद जानकारी के लिए टिप्पणियों पर भरोसा नहीं करना चाहिए।


3
बहुत आसान है, हालांकि - मैं पैरामीटर जाँच ;-p के लिए एक "ThrowIfNull` विस्तार विधि है
— मार्क Gravell

2
तुम यह केर सकते हो? ugh ThrowIfNull यह दिलचस्प विस्तार है लेकिन यह सिर्फ गलत लगता है।
— जोशबर्के

1
सादे सीएलआर में आप अशक्त संदर्भों पर उदाहरण विधियों को लागू कर सकते हैं और यदि विधि ऑब्जेक्ट तक नहीं पहुंचती है या यह फ़ील्ड है तो कॉल शून्य संदर्भ अपवाद को नहीं फेंकती है। (आप इसे C # में नहीं कर सकते क्योंकि यह गैर आभासी तरीकों के लिए भी कॉलविर्ट का उपयोग करता है)
— पॉप

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

3
@Will: अपवाद हैंडलिंग जावा और .net दोनों में icky है, क्योंकि तंत्र ने तीन अवधारणाओं को एक साथ सम्‍मिलित किया है, जो कुछ संबंधित हैं, लेकिन कुछ हद तक रूढ़िवादी भी हैं: (1) किस प्रकार की चीज गलत हो गई (एक सरणी सीमा त्रुटि) एक I / O टाइमआउट, आदि); (२) परिणाम के रूप में कुछ कोड पर कार्रवाई होनी चाहिए या नहीं; (३) समस्या को किस बिंदु पर "हल" माना जाना चाहिए। एक रूटीन पर विचार करें जो एक IEnumerable से पढ़े गए डेटा के साथ किसी वस्तु को बदलना है। यदि उस IEnumerable के प्रसंस्करण में कोई अपवाद होता है तो क्या होना चाहिए?
— सुपरकैट

3

.Parameters.Add () फ्रेमवर्क के V1 में SqlCommand पर विधि बुरी तरह से डिजाइन की गई थी - ओवरलोड में से एक मूल रूप से काम नहीं करेगा यदि आप 0 के मान (int) के साथ एक पैरामीटर में पास हुए - तो उन्हें बनाने के लिए नेतृत्व किया .Parameters.AddWithValue () SqlCommand वर्ग पर विधि।


मैं सहमत हूं, लेकिन मुझे लगता है कि आप SqlCommand.Parameters.Add () विधि का मतलब है।
— मैट पीटरसन

3
  1. का कोई सबसेट नहीं है ICollection<T>और IList<T>; कम से कम, एक सहसंयोजक रीड-ओनली कलेक्शन इंटरफेस IListSource<out T>(एन्यूमरेटर, इंडेक्सर और काउंट के साथ) बेहद उपयोगी होता।
  2. .NET कमजोर प्रतिनिधियों का समर्थन नहीं करता है । वर्कअराउड सबसे अच्छा अनाड़ी हैं, और आंशिक पक्ष में श्रोता-साइड वर्कआर्डर्स असंभव हैं (ReflectionPermission की आवश्यकता है)।
  3. सामान्य इंटरफ़ेस एकीकरण तब भी निषिद्ध है जब यह समझ में आता है और कोई समस्या पैदा नहीं करता है।
  4. C ++ के विपरीत, सहसंयोजक वापसी प्रकार .NET में की अनुमति नहीं है
  5. समानता के लिए दो मूल्य प्रकारों को बिटवाइज़-तुलना करना संभव नहीं है। एक कार्यात्मक " लगातार " डेटा संरचना में, मैं लिख रहा थाTransform(Sequence<T>, Func<T,T>) फ़ंक्शन जिसे यह निर्धारित करने की आवश्यकता थी कि फ़ंक्शन समान मान या अलग मान लौटाता है या नहीं। यदि फ़ंक्शन अपने अधिकांश तर्कों को संशोधित नहीं करता है, तो आउटपुट अनुक्रम इनपुट अनुक्रम से कुछ / सभी मेमोरी साझा कर सकता है। किसी भी मूल्य प्रकार टी की तुलना करने की क्षमता के बिना, एक बहुत धीमी तुलना का उपयोग किया जाना चाहिए, जो प्रदर्शन को जबरदस्त चोट पहुंचाता है।
  6. .NET एक तदर्थ तरीके से तदर्थ इंटरफेस (जैसे गो या रस्ट में पेश किए गए) का समर्थन करने में सक्षम नहीं लगता है। इस तरह के इंटरफेस ने आपको List<T>एक काल्पनिक IListSource<U>(जहां टी: यू) के लिए कास्ट करने की अनुमति दी होगी, भले ही वर्ग उस इंटरफ़ेस को स्पष्ट रूप से लागू नहीं करता है। इस कार्यक्षमता की आपूर्ति करने के लिए कम से कम तीन अलग-अलग पुस्तकालय (स्वतंत्र रूप से लिखे गए) हैं, प्रदर्शन की कमियों के साथ, निश्चित रूप से - यदि एक सही समाधान संभव था, तो इसे .NET में दोष कहना उचित नहीं होगा)।
  7. अन्य प्रदर्शन मुद्दे: IEnumerator प्रति पुनरावृत्ति दो इंटरफ़ेस कॉल की आवश्यकता है। सादा विधि संकेत (इंटप्रा-आकार के खुले प्रतिनिधि) या मूल्य-टाइप किए गए प्रतिनिधि (इंटप्रे * 2) संभव नहीं हैं। निश्चित आकार के सरणियों (मनमाने प्रकार के टी) को कक्षाओं के अंदर एम्बेड नहीं किया जा सकता है। कोई नहीं है WeakReference<T>(आप आसानी से अपना लिख ​​सकते हैं, लेकिन यह आंतरिक रूप से कलाकारों का उपयोग करेगा।)
  8. तथ्य यह है कि समान प्रतिनिधि प्रकार असंगत माना जाता है (कोई अंतर्निहित रूपांतरण) (जैसे कुछ अवसरों पर मेरे लिए एक बाधा कर दिया गया है Predicate<T>बनाम Func<T,bool>)। मैं अक्सर चाहता हूं कि हम घटकों के बीच ढीले युग्मन को प्राप्त करने के लिए इंटरफेस और प्रतिनिधियों के लिए संरचनात्मक टाइपिंग कर सकते हैं , क्योंकि .NET में स्वतंत्र DLL में कक्षाओं के लिए समान इंटरफ़ेस लागू करने के लिए यह पर्याप्त नहीं है - उन्हें एक तिहाई के लिए एक सामान्य संदर्भ भी साझा करना होगा DLL जो इंटरफ़ेस को परिभाषित करता है।
  9. DBNull.Valueमौजूद है, भले ही nullएक ही उद्देश्य समान रूप से अच्छी तरह से सेवा की है।
  10. सी # में कोई नहीं है = = ऑपरेटर; आप अवश्य लिखें variable = variable ?? value। वास्तव में, C # में कुछ स्थान हैं, जिनमें अनावश्यक रूप से समरूपता की कमी है। उदाहरण के लिए आप if (x) y(); else z();(ब्रेसिज़ के बिना) लिख सकते हैं, लेकिन आप नहीं लिख सकते try y(); finally z();।
  11. एक धागा बनाते समय, बच्चे के धागे को मूल धागा से थ्रेड-स्थानीय मान विरासत में लेने के लिए असंभव है। न केवल बीसीएल इस का समर्थन नहीं करता है, लेकिन आप इसे स्वयं लागू नहीं कर सकते हैं जब तक कि आप मैन्युअल रूप से सभी धागे नहीं बनाते हैं; भले ही कोई थ्रेड-निर्माण ईवेंट था, .NET आपको किसी दिए गए थ्रेड के "माता-पिता" या "बच्चे" नहीं बता सकता है ।
  12. तथ्य यह है कि विभिन्न डेटा प्रकारों के लिए दो अलग-अलग लंबाई की विशेषताएं हैं, "लंबाई" और "गणना", एक मामूली उपद्रव है।
  13. मैं हमेशा के लिए WPF ... और WCF (हालांकि कुछ परिदृश्यों के लिए काफी उपयोगी) के खराब डिजाइन के बारे में आगे बढ़ सकता है। सामान्य तौर पर, बीसीएल के कई नए पुस्तकालयों में ब्लोटनेस, अनइंस्टिट्यूट, और सीमित प्रलेखन मुझे उनका उपयोग करने के लिए अनिच्छुक बनाता है। बहुत सारे नए सामान अधिक सरल, छोटे, उपयोग करने में आसान और समझने में आसान, अधिक शिथिल युग्मित, बेहतर-प्रलेखित, अधिक उपयोग के मामलों के लिए लागू, तेज और / या अधिक दृढ़ता से टाइप किए जा सकते थे।
  14. मुझे अक्सर संपत्ति पाने वालों और बसने वालों के बीच अनावश्यक कपलिंग द्वारा काट लिया गया है: एक व्युत्पन्न वर्ग या व्युत्पन्न इंटरफ़ेस में, आप बस एक सेटर नहीं जोड़ सकते जब आधार वर्ग या आधार इंटरफ़ेस में केवल एक गेट्टर होता है; यदि आप एक गॉटर को ओवरराइड करते हैं तो आपको एक सेटर को परिभाषित करने की अनुमति नहीं है; और आप सेटर को आभासी के रूप में परिभाषित नहीं कर सकते हैं लेकिन गैर-वर्चुअल के रूप में।

मैं आपके साथ एक सबसेट के बारे में सहमत हूँ IList<T>, हालाँकि मैं उपयोग करूँगा IReadableByIndex<out T>और IAppendable<in T>। आपकी कई अन्य बातें हैं, मैं उन लोगों के साथ भी सहमत हूँ।
— सुपरकैट

यह वास्तव में लंबा नाम है। शायद हम इससे समझौता कर सकते हैं IListReader<T>;) - मैं "सिंक" के शब्द के रूप में "स्रोत" शब्द का उपयोग करता हूं (केवल लिखने के लिए इंटरफ़ेस)।
— क्वर्टी जू

शायद IListSource<in T>या IReadableList<out T>। आधार इंटरफ़ेस प्रकार होने में मूल्य हो सकते हैं, ऐसे तरीके शामिल हैं जो सभी डेरिवेटिव में मौजूद नहीं हैं, हालांकि मुझे लगता है कि इंटरफेस को अक्सर कुछ विशेष होना अच्छा होता है। उदाहरण के लिए, कोई ऐसा हो सकता है IList<T>जिसमें आकार बदलने के तरीके शामिल हों जो काम नहीं कर सकते या नहीं कर सकते हैं, और IResizableList<T>जो एक ही तरीकों को लागू करता है, लेकिन गारंटी देता है कि उन्हें काम करना चाहिए। इस तरह का दृष्टिकोण उन मामलों में उपयोगी हो सकता है जहां एक क्षेत्र या तो एक उत्परिवर्तित सूची के लिए केवल एक ही संदर्भ, या एक अपरिवर्तनीय के लिए एक साझा संदर्भ रख सकता है।
— सुपरकैट

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

@supercat यह केवल एक ही बात है क्योंकि C # यह जांचने के लिए एक आसान तरीका प्रदान नहीं करता है कि एक इंटरफ़ेस लागू किया गया है और तुरंत उसका उपयोग करें। एमएस को आसान बनाने के लिए एक भाषा सुविधा को जोड़ना चाहिए। मेरी पसंदीदा तकनीक एक बाध्यकारी अभिव्यक्ति होगी if (rl:(list as IResizableList<T>) != null) rl.Add(...);, लेकिन अन्य प्रस्ताव भी हैं। विभिन्न संग्रहों और संग्रह एडेप्टर के लेखक के रूप में, मुझे जो भी परेशान करता है वह बहुत सारे डमी तरीके लिख रहा है जो अपवादों को फेंकते हैं। एक प्रकार के सुरक्षा प्रशंसक के रूप में, मैं अवैध तरीकों को कॉल करने की अनुमति नहीं देना चाहता। एक IntelliSense प्रशंसक, मैं उन्हें सूचीबद्ध नहीं देखना चाहता।
— Qwertie

2

एक बात है कि मुझे 1.x में बंद टिक का उपयोग करते समय था System.Xml.XmlValidatingReader, ValidationEventHandlerके ValidationEventArgsखुलासा नहीं करता अंतर्निहित XmlSchemaException(आंतरिक चिह्नित), जो की तरह सभी उपयोगी जानकारी है linenumberऔर position। इसके बजाय आप संदेश स्ट्रिंग संपत्ति से बाहर पार्स करने के लिए या इसे खोदने के लिए प्रतिबिंब का उपयोग करने की उम्मीद कर रहे हैं। इतना अच्छा नहीं है जब आप अंतिम उपयोगकर्ता के लिए एक अधिक संचित त्रुटि वापस करना चाहते हैं।


1

यह पसंद नहीं है कि आप एक और एनम में एक एनम के मूल्यों का उपयोग नहीं कर सकते हैं, उदाहरण के लिए:

    enum Colors { white, blue, green, red, black, yellow }

    enum SpecialColors { Colors.blue, Colors.red, Colors.Yellow } 

2
हालांकि यह भी समझ में नहीं आता है। typeof(Color)! = typeof(SpecialColors)।
— कर्क वोक

10
यह करना काफी आसान है:enum SpecialColors { blue = Colors.blue, red = Colors.red, yellow = Colors.Yellow }
— ट्रिस्टन स्पैन्गलर

0

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

MSDN से:

  • var का उपयोग केवल तब किया जा सकता है जब एक स्थानीय चर घोषित किया जाता है और एक ही कथन में आरम्भ किया जाता है; चर को शून्य, या विधि समूह या अनाम फ़ंक्शन के लिए प्रारंभ नहीं किया जा सकता है।
  • var का उपयोग फ़ील्ड स्कोप पर फ़ील्ड में नहीं किया जा सकता है।
  • Var का उपयोग करके घोषित चर का उपयोग इनिशियलाइज़ेशन एक्सप्रेशन में नहीं किया जा सकता है। दूसरे शब्दों में, यह अभिव्यक्ति कानूनी है: int i = (i = 20); लेकिन यह अभिव्यक्ति एक संकलन-समय त्रुटि पैदा करती है: var i = (i = 20);
  • एकाधिक निहित-टाइप किए गए चर को एक ही कथन में प्रारंभ नहीं किया जा सकता है।
  • यदि एक प्रकार का नाम var कार्यक्षेत्र में है, तो var कीवर्ड उस प्रकार के नाम को हल कर देगा और इसे अनुमानित रूप से टाइप किए गए स्थानीय चर घोषणा के हिस्से के रूप में नहीं माना जाएगा।

मुझे लगता है कि यह खराब क्रियान्वयन का कारण है कि वे इसे संस्करण कहते हैं, लेकिन यह एक संस्करण होने से एक लंबा रास्ता तय करता है। यह वास्तव में सिर्फ शॉर्टहैंड सिंटैक्स है जिसमें पूरी तरह से क्लास का नाम नहीं लिखा जाता है (जब लिंच के साथ प्रयोग किया जाता है)


निश्चित रूप से तुरन्त प्रकार (नई {...}), परोक्ष टाइप नहीं (वर)
— मार्क Gravell

बस जो मैंने पोस्ट किया था उसे दोबारा पढ़ें और यह गलत था। मेरा मतलब था कि स्पष्ट रूप से टाइप किए गए चर tho
— lomaxx

1
एरिक लिपर्ट ने बताया कि विभिन्न विधियों के बाहर var का उपयोग क्यों नहीं किया जा सकता है, यह मूल रूप से है क्योंकि यह संभावनाओं का एक ब्लैक बॉक्स बनाता है। blogs.msdn.com/ericlippert/archive/2009/01/26/…
— ग्वेंटे

1
var का उद्देश्य भिन्न होना नहीं है! यह शॉर्टहैंड (विशेष रूप से एनोन प्रकार) के लिए ठीक है। गतिशील का आनंद लें जब यह साथ आता है ...
— ShuggyCoUk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.