2009-02-16 20 views
6

यह संपत्तियों के साथ VB.NET में संभव नहीं लगता है क्योंकि संपत्ति विवरण स्वयं को यह वर्णन करना चाहिए कि यह ReadOnly है या नहीं।इसे पढ़ने/लिखने के लिए एक सबक्लास में केवल पढ़ने के लिए ओवरराइड करना (VB.NET या C#)

नीचे दिए गए मेरे उदाहरण में, यह मुझे ReadWriteChild संकलन करने नहीं देता है। मुझे लगता है कि मैं माता-पिता को पढ़/लिख सकता हूं, और फिर ReadOnlyChild के सेटर कुछ भी नहीं कर सकता है, लेकिन ऐसा लगता है कि हैकी की तरह। सबसे अच्छा विकल्प इस मामले में गेटर/सेटर विधियों के पक्ष में संपत्तियों को त्यागना प्रतीत होता है।

Public MustInherit Class Parent 

    Public MustOverride ReadOnly Property Foo() As String 

End Class 

Public Class ReadOnlyChild 
    Inherits Parent 

    Public Overrides ReadOnly Property Foo() As String 
     Get 
      ' Get the Property 
     End Get 
    End Property 

End Class 

Public Class ReadWriteChild 
    Inherits Parent 

    Public Overrides Property Foo() As String 
     Get 
      ' Get the property. 
     End Get 
     Set(ByVal value As String) 
      ' Set the property. 
     End Set 
    End Property 

End Class 
+0

मुझे नहीं लगता कि आप ऐसा कर सकते है कि VB.NET में क्या आवश्यकता होगी, के लिए अपने तर्क है (किसी के बारे में मुझे गलत साबित करने के लिए है): दुर्भाग्य से, एक ही रास्ता करने के लिए वास्तव में गुंजाइश चीजें ठीक से नेस्टेड वर्गों का उपयोग करने के लिए है ऐसा करने के लिए, यदि यह आपके स्वयं के वर्गों में से एक है तो निश्चित रूप से यह डिज़ाइन में त्रुटि इंगित करता है ... या हो सकता है कि इंटरफेस बीटर का इस्तेमाल किया गया हो? – spacemonkeys

+0

मेरे मामले में, संपत्ति अधिकांश उपप्रकारों के लिए प्रभावी रूप से सच है, लेकिन वहां एक कहा गया है जहां संपत्ति संपादन योग्य है। अभी मैं टाइप चेक का उपयोग कर रहा हूं, लेकिन एक अतिव्यापी संपत्ति अधिक उपयुक्त होगी। –

उत्तर

6

जो भी आप पूरा करने की कोशिश कर रहे हैं, और आपके द्वारा पोस्ट किए गए नमूना कोड के साथ, VB.NET आपको ऐसा करने नहीं देगा।

आमतौर पर, आप तो जैसे VB.NET में एक संपत्ति की घोषणा कर सकते हैं:

Public Class qwqwqw 
    Public Property xyz() As String 
     Get 
      Return "" 
     End Get 
     Private Set(ByVal value As String) 
      ' 
     End Set 
    End Property 
End Class 

मूल रूप से सार्वजनिक रूप समग्र संपत्ति अंकन, लेकिन सेटर (या गेटर) के लिए एक अधिक प्रतिबंधात्मक गुंजाइश दे रही है।

आपके मामले में मुख्य समस्या MustInherit (i.e. abstract) बेस क्लास है। चूंकि आप जिस संपत्ति को परिभाषित कर रहे हैं उसे मोस्टोवरराइड के रूप में चिह्नित किया गया है, इसलिए आप एक डिफ़ॉल्ट कार्यान्वयन (यानी यह भी, अमूर्त है) प्रदान नहीं कर सकते हैं, और इसमें "प्राप्त करें" और "सेट" रूपरेखा शामिल हैं, इसलिए, जो भी "समग्र" "इस अमूर्त संपत्ति घोषणा को आप जो दायरा देते हैं, वीबीएनईटी आपको दोनों व्युत्पन्न कक्षाओं के भीतर गेटर्स और सेटर्स के लिए इस दायरे का उपयोग करने के लिए मजबूर करेगा।

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

उदाहरण के लिए:

Public MustInherit Class Parent 
    Public MustOverride Property Foo() As String 
End Class 

Public Class ReadOnlyChild 
    Inherits Parent 

    Public Overrides Property Foo() As String 
    Get 
     ' 
    End Get 
    Private Set(ByVal value As String) 
     ' 
    End Set 
    End Property 
End Class 

(सेटर पर निजी scoping नोट)। यह काम नहीं करेगा क्योंकि वीबीएनईटी जोर दे रहा है कि चूंकि आप बेस क्लास प्रॉपर्टी को ओवरराइड कर रहे हैं, इसलिए आपकी पूरी संपत्ति में वही संपत्ति होनी चाहिए, जिसकी संपत्ति आप ओवरराइड कर रहे हैं (इस मामले में, सार्वजनिक)।

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

इसलिए

:

Public MustInherit Class Parent 
    Protected MustOverride Property Foo() As String  
End Class 

Public Class ReadOnlyChild 
    Inherits Parent 

    Protected Overrides Property Foo() As String 
     Public Get 
      ' 
     End Get 
     Set(ByVal value As String) 
      ' 
     End Set 
    End Property 
End Class 

(गेटर पर सार्वजनिक scoping नोट)। सार्वजनिक क्षेत्र के संरक्षित होने के कुल संपत्ति दायरे से कम प्रतिबंधित होने के कारण या तो आधार वर्ग की अमूर्त संपत्ति घोषणा पर परिभाषित समान स्कोपिंग स्तर की वजह से काम नहीं करता है।

तो अपनी कक्षाओं के डिजाइन के रूप में आप अपने प्रश्न में उल्लेख है, मैं व्यक्तिगत रूप से, एक "जावा शैली" गेटर और सेटर तरीकों के रूप में वे तो अपने स्वयं के scoping के स्तर के साथ अलग से घोषित किया जा सकता के साथ जाना होगा।

+0

अफसोस की बात है, यह परेशानी सी # के बारे में भी सच है। –

+0

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

3

एक longshot ... यह देखते हुए कि VB.NET की मेरी जानकारी कम है हो सकता है ...

सी # में आप संपत्ति की स्वतंत्र रूप से एक संपत्ति एक्सेसर की दृश्यता निर्दिष्ट कर सकते हैं:

public virtual string Name 
{ 
    get { ... } 
    protected set { ... } 
} 

इस उदाहरण में, बाल कक्षाएं बसने वाले तक पहुंच सकती हैं, लेकिन अन्य कक्षाएं नहीं कर सकती हैं।

यह भी ध्यान रखें कि वे क्या ओवरराइड ओवरराइड से अधिक दृश्यता हो सकता है - तो आप ऐसा कर सकते हैं:

public overide string Name 
{ 
    get { ... } 
    public set { ... } 
} 

आप VB.NET में कुछ इस तरह कर सकते हैं?

0

दुर्भाग्यवश मुझे यहां पर दृश्य स्टूडियो नहीं मिला है इसलिए मैं पुष्टि नहीं कर सकता।

क्या आपने छाया का उपयोग करने पर ध्यान दिया है, यह प्रभावी रूप से सी # संपत्ति घोषणा में "नया" कहने जैसा ही है।

2

पुष्टि करें कि श्री एडमुनो सही है कि आप छाया का उपयोग कर सकते हैं। हालांकि ऐसा प्रतीत होता है कि आप किसी भी चीज को सीधे हिस्टिनेट चिह्नित नहीं कर सकते हैं, इसलिए आपको कक्षा (अभिभावक 2) में वारिस करने की आवश्यकता है ... फिर अपने पाठ में (वास्तव में इसके बारे में सोचने के लिए आपको शायद छाया का उपयोग करने की आवश्यकता नहीं है यदि आप एक कक्षा में उत्तराधिकारी)

मुझे लगता है कि मेरी टिप्पणी प्रश्न अभी भी खड़ा है, आपको ऐसा करने की आवश्यकता क्यों है? यदि वे आपकी खुद की कक्षाएं हैं तो क्या आप उनको संशोधित करना बेहतर करेंगे, या इंटरफ़ेस के रूप में कार्यान्वित करेंगे?

Public MustInherit Class Parent 

    Public MustOverride ReadOnly Property Foo() As String 

End Class 

Public Class ReadOnlyChild 
    Inherits Parent 

    Public Overrides ReadOnly Property Foo() As String 
     Get 
      'Get the Property 
      Return "Return" 
     End Get 
    End Property 

End Class 

Public Class Parent2 
    Inherits Parent 

    Public Overrides ReadOnly Property Foo() As String 
     Get 
      Return "Return 2" 
     End Get 
    End Property 
End Class 

Public Class ReadWriteChild 
    Inherits Parent2 

    Public Shadows Property Foo() As String 
     Get 
      '// Get the property. 
      Return "2" 
     End Get 
     Set(ByVal value As String) 
      '** Set something 
     End Set 
    End Property 
0

क्या बेवन का सुझाव दिया, VB.NET में यदि आप किसी सार्वजनिक गेटर और एक संरक्षित सेटर होने के रूप में एक संपत्ति घोषित कर सकते हैं, इस प्रकार से निपटने के लिए:

Private _ExpectedTotalRoyalties As Decimal 

Public Property ExpectedTotalRoyalties() As Decimal 
    Get 
     Return _ExpectedTotalRoyalties 
    End Get 
    Protected Set(ByVal value As Decimal) 
     If Not _ExpectedTotalRoyalties.Equals(value) Then 
      _ExpectedTotalRoyalties = value 
      SendPropertyChanged("ExpectedTotalRoyalties") 
     End If 
    End Set 
End Property 
0

के बाद से संपत्ति को ओवरराइड करने की कोशिश मत करो यह आभासी नहीं है। OnReadOnlyChanged विधियों को ओवरराइड करें और वहां अपने व्यवसाय को संभालें। शुभकामनाएं

0

आपको पदानुक्रम का एक और स्तर जोड़ने की आवश्यकता है;

Public Class IntermediateClassForPrivateInheritanceOnly 
    Inherits Parent 
    Public Overrides ReadOnly Property Foo() As String 
    ' etc. 
    Private Sub New(whatever) 
    MyBase.New(whatever) 
    End Sub 

    ' Most other stuff for the class goes here. 

    Public Class ReadWriteChild 
    Inherits IntermediateClassForPrivateInheritanceOnly 
    Shadows Property Foo() 
    ' etc. 
    Public Sub New(whatever) 
     MyBase.New(whatever) 
    End Sub 
    End Class 
End Class 

Public Class ReadWriteChild ' Would use an alias, if such things existed 
    Inherits IntermediateClassForPrivateInheritanceOnly 
    Public Sub New(whatever) 
    MyBase.New(whatever) 
    End Sub 
End Class