2012-04-11 13 views
25

मैं थोड़ी देर के लिए सोच रहा है यही कारण है कि सी # कक्षा या एक विधि स्तर पर const समर्थन नहीं करता। मुझे पता है कि जॉन स्कीट लंबे समय तक अपरिवर्तनीयता के लिए समर्थन चाहते थे, और मैं फिर से काम करता हूं कि फंक्शन कॉन्स के सी ++ सिंटैक्स का उपयोग करने में सहायता मिल सकती है। कक्षा स्तर पर एक कॉन्स कीवर्ड जोड़कर हम कुल समर्थन प्राप्त करेंगे।सी # समर्थन कक्षा/विधि स्तर पर क्यों नहीं है?

अब, मेरे सवाल है, क्या कारण सी # टीम के लिए है समर्थन के इस प्रकार विकसित किया है नहीं करने के लिए?

मैं सब कुछ कल्पना CLR बार बदले बिना एक संकलन समय चेक के साथ या विशेषताओं के माध्यम से बनाया जा सकता है। मुझे लगता है कि कोड प्रतिबिंब के माध्यम से कॉन्स व्यवहार को ओवरराइड करने में सक्षम नहीं है।

इस कल्पना कीजिए:

const class NumberContainer 
{ 
    public int Number { get; } 
} 

.. इस तरह के एक वर्ग केवल निर्माण समय में आबादी किया जा सकता है, तो हम एक निर्माता आवश्यकता होगी किसी पूर्णांक में लेने के लिए।

एक और उदाहरण के लिए एक विधि-स्तर पर स्थिरांक है:

public int AddNumbers(NumberContainer n1, NumberContainer n2) const 
{ 
    return n1.Number + n2.Number; 
} 

कॉन्स्ट स्तर की विधियों को अपने ही वर्ग या संदर्भ प्रकार उन्हें पारित मामलों में स्थिति में परिवर्तन करने में सक्षम नहीं होना चाहिए। इसके अलावा, कॉन्स्ट-स्तरीय फ़ंक्शंस केवल अपने दायरे में अन्य कॉन्स्ट-स्तरीय फ़ंक्शंस का आह्वान कर सकता है।

मैं सच में यकीन है कि अगर lambdas और प्रतिनिधियों बहुत कठिन सब कुछ होगा (या असंभव) प्राप्त करने के लिए नहीं कर रहा हूँ, लेकिन मैं भाषा और संकलक डिजाइन मुझे बता सकते में और अधिक अनुभव के साथ यकीन है कि किसी को कर रहा हूँ।

स्टीव बी टिप्पणी में कहा, readonly के अस्तित्व चीज़ें थोड़ी अधिक जटिल, स्थिरांक के रूप में आता है और readonlyruntime के दौरान एक ही के करीब हैं, लेकिन readonly मूल्यों संकलन समय के दौरान निर्धारित नहीं किया जा सकता है। मुझे लगता है कि हमारे पास const और readonly स्तर हो सकता है लेकिन यह बहुत भ्रमित हो सकता है?

तो, यह लागू नहीं करने के लिए कारण क्या है? प्रयोज्य चिंताओं (अधिक अचल स्थिति-चर्चा के दिनों कर रहे हैं) (सी ++ में constness समझने आम तौर पर काफी नए उपयोगकर्ताओं के लिए मुश्किल), भाषा डिजाइन चिंताओं (नहीं किया जा सकता) या बस प्राथमिकता चिंताओं ..?

+0

'readonly' कीवर्ड आपकी आवश्यकता को संभाल नहीं करता है? –

+0

ओप्स, मेरा बुरा .. मुझे पढ़ने के बारे में बहुत कुछ सोचा था, लेकिन इसे पोस्ट करना भूल गया। मेरे विचार-प्रक्रिया को अपडेट कर देगा .. – cwap

+7

आप मूल रूप से पूछ रहे हैं "भाषा में एक्स क्यों विशेषता नहीं है" - सरल: या तो इसे प्रस्तावित नहीं किया गया है + माना जाता है + अनुमोदित + स्कॉप्ड + डिज़ाइन + अपूर्ण + परीक्षण + दस्तावेज + तैनात (उस संसाधन के लिए अन्य संभावित उपयोगों और भाषा ब्लोट के प्रभाव के खिलाफ वजन), या * उनमें से कुछ * पर विचार किया गया था और इसे अवांछनीय, या स्थगित कर दिया गया था। यह स्वचालित नहीं है कि प्रत्येक भाषा को कल्पना की जाने वाली हर सुविधा मिलती है। –

उत्तर

24

कुछ हद तक परिपत्र स्पष्टीकरण को जोखिम देना, सी # कॉन्स का समर्थन नहीं करता है क्योंकि सीएलआर के लिए इसका कोई समर्थन नहीं है। सीएलआर इसका समर्थन नहीं करता है क्योंकि यह काफी गैर-सीएलएस अनुपालन है।

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

कॉन्स्ट-नेस के साथ समस्या यह है कि इसे लागू किया जाना चाहिए। यह सी # में एक समस्या है जब एक मनमानी अन्य भाषा सी # कक्षा का उपयोग कर सकती है और पूरी तरह से कॉन्स्टेस को अनदेखा कर सकती है क्योंकि भाषा इसका समर्थन नहीं करती है। इसे अन्य सभी सीएलएस भाषा पर बोल्ट करना क्योंकि सी # इसका समर्थन करता है, यह बिल्कुल अनैतिक है।

लागू करने योग्यता सी ++ में भी एक समस्या है। क्योंकि भाषा const_cast <> का भी समर्थन करती है। कोई भी ग्राहक कोड कॉन्स-नेस को तेज़ी से और अविभाज्य रूप से दूर कर सकता है। आपको नहीं माना जाता है, लेकिन फिर कभी-कभी आपको करना होता है। क्योंकि दो तरह के कॉन्स्टेस, सख्त और देखने योग्य हैं। निजी कॉन्स्टेस और सार्वजनिक कॉन्स्टेस के समान रूप से समान है। परिवर्तनीय कीवर्ड को बाद में भाषा में जोड़ा गया ताकि देखने योग्य कॉन्स-नेस की आवश्यकता से निपटने का प्रयास किया जा सके ताकि कम से कम const_cast <> के अनिवार्य उपयोग से बचा जा सके। कुछ लोग कहते हैं कि सी ++ एक कठिन भाषा है। सी # ज्यादा की बात मत सुनो।

+0

सर्वश्रेष्ठ उत्तर समझ में नहीं आता। बहुत बहुत धन्यवाद, बहुत समझ में आता है! – cwap

3

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

2

के रूप में मेरा मानना ​​है कि होने के लिए मामला है, const अलग बातें सी # में सी ++ की तुलना का मतलब है।

सी # में आप const से इच्छित कार्यक्षमता का स्तर प्राप्त करने के लिए readonly कीवर्ड का उपयोग कर सकते हैं।

1

एक स्थिरांक-वर्ग के लिए अपने प्रस्ताव के मामले में, आप कहते हैं:

इस तरह के एक वर्ग केवल निर्माण समय में आबादी किया जा सकता है, तो हम एक निर्माता आवश्यकता होगी किसी पूर्णांक

में लेने के लिए

लेकिन सभी गुण केवल पढ़ने के लिए वैसे भी आप पहले से ही हासिल किया है कि तुम क्या कहा है बनाकर।

मैं सी # भाषा डिजाइनरों के लिए बात नहीं कर सकता लेकिन शायद const नहीं होने का कारण कई अन्य संरचनाओं पर लागू होता है क्योंकि यह जोड़ना केवल प्रयास के लायक नहीं था और आप इस मुद्दे को अन्य तरीकों से प्राप्त कर सकते हैं (ऊपर वर्णित अनुसार और अन्य उत्तरों/टिप्पणियों में)।

1

मैं आपके प्रश्न से नहीं कह सकता कि const कीवर्ड का यह ओवरलोडिंग विशेष रूप से फायदेमंद होगा।

आपका पहला उदाहरण

public class NumberContainer 
{ 
    private readonly int number; 

    public NumberContainer(int number) 
    { 
     this.number = number; 
    } 

    public int Number 
    { 
     get { return number; } 
    } 
} 

के रूप में कानूनी तौर पर फिर से लिखा जा सकता है शायद, अगर संकलक इस वर्ग (मैं नहीं जानता) की अचल विचार करने में असमर्थ है, कुछ विशेषताओं को उपयोगी हो सकता है?

आपके दूसरे उदाहरण में, मुझे समझ में नहीं आता कि आप क्या चल रहे हैं। यदि कोई फ़ंक्शन निरंतर मान देता है तो इसे निरंतर फ़ील्ड से बदला जा सकता है।

2

मैं एक बार निम्न स्थिति से surpised था:

class Vector 
{ 
    private double[] m_data; 
    public int Dimension {get;set;} 

    public double this[int i] 
    { 
     get {return m_data[i];} 
     set {m_data[i] = value;} 
    } 

    public Vector(int n) 
    { 
     this.Dimension = n; 
     this.m_data = new double(n); 
    } 

    public static Vector Zero(int n) 
    { 
     Vector v = new Vector(n); 
     for (int i = 0; i < n; i++) 
     { 
      v[i] = 0.0; 
     } 

     return v; 
    } 

    public static readonly Vector Zero3 = Zero(3); 
} 

तू Vector.Zero3 केवल पढ़ने के लिए है और आप इसे करने के लिए असाइन नहीं कर सकते, तो आप अभी भी अपने घटक उपयोग कर सकते हैं, और फिर निम्न बेवकूफ बात होता है:

Vector a = Vector.Zero3; 
a[0]  = 2.87; 

और अब, के बाद से एक IST कुछ भी नहीं लेकिन Vector.Vector3 के लिए एक संदर्भ बाद भी Vector.Vector3 [0] == 2.87 है!

एक बार जब मैं इस गड्ढे में गिर गया, तो मैंने एक बहुत ही सरल हैक का आविष्कार किया, हालांकि सुरुचिपूर्ण नहीं, इसके कार्य को पूरा करता है।

class Vector 
{ 
    private double[] m_data; 
    public int Dimension {get;set;} 
    private bool m_bIsConstant = false; 
    ... 

    public double this[int i] 
    { 
     get {return m_data[i];} 
     set 
     { 
      if (!m_bIsConstant) 
      { 
       m_data[i] = value; 
      } 
     } 
    } 
    ... 
    public static Vector Zero(int n) 
    { 
     Vector v = new Vector(n); 
     for (int i = 0; i < n; i++) 
     { 
      v[i] = 0.0; 
     } 

     v.m_bIsConstant = true; 
     return v; 
    } 
    ... 
} 

इस हैक गारंटी देता है कि आपके स्थिर केवल पढ़ने के लिए चर संशोधित किया जा कभी नहीं होगा:

अर्थात्, एक वर्ग है कि मैं स्थिर केवल पढ़ने के लिए "स्थिरांक" का निर्माण करने के लिए लगता में, मैं एक बूलियन ध्वज परिचय।

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