2012-12-29 11 views
5

में व्युत्पन्न प्रकार की वस्तु का निर्माण करना क्या यह vb.net में एक विधि है जो बास वर्ग में किसी भी व्युत्पन्न कक्षा का ऑब्जेक्ट बनाता है? इस कोड में x.Clone को एक बार ऑब्जेक्ट वापस करना चाहिए। दोनों वर्गों में कोड को अलग-अलग ऑब्जेक्ट प्रकारों के साथ कोड को डुप्लिकेट करने का एकमात्र तरीका है।बेस ऑब्जेक्ट

Module Module1 

    Sub Main() 
     Dim x As New Bar 
     Dim y As Bar = x.Clone 
    End Sub 

End Module 

Public Class Foo 
    Implements ICloneable 
    Public Function Clone() As Object Implements System.ICloneable.Clone 
     Clone = Me.new() 'fails to compile as not in a constructor 
     Clone = new Foo 'constructs a new foo in the derived class 
    End Function 
End Class 

Public Class Bar 
    Inherits Foo 
    'additional implementation 
    'but no addition fields 
End Class 

उत्तर

3

उत्तर विशेष रूप से क्लोनिंग विधि में पूरा करने की कोशिश कर रहे हैं पर निर्भर करता है।

यदि आप वास्तव में किसी भी गुण की प्रतिलिपि बनाते हुए वर्तमान कक्षा का एक नया उदाहरण बनाना चाहते हैं (जो लगता है जैसे आप नमूना कोड और विवरण के आधार पर करने में रुचि रखते हैं), तो सरल समाधान है:

Public Class Foo 
    Implements ICloneable 

    Public Function Clone() As Object Implements System.ICloneable.Clone 
     Return Activator.CreateInstance(Me.GetType) 
    End Function 
End Class 

आप एक संदेश (या डिबग या उत्पादन के कुछ प्रकार) बार में जोड़कर परीक्षण कर सकते हैं कि इस कहा जाता है:

Public Class Bar 
    Inherits Foo 

    Public Sub New() 
     MsgBox("Test") 
    End Sub 

End Class 

आप Option Strict On है, जो मैं दृढ़ता से मुख्य में सलाह देते हैं, कोड है, तो होगा:

Sub Main() 
    Dim x As New Bar 
    Dim y As Bar = DirectCast(x.Clone, Bar) 
End Sub 

हालांकि, अगर आप वर्तमान वर्ग से सदस्य मूल्यों को कॉपी में रुचि रखते हैं, तो आप MemberwiseClone उपयोग कर सकते हैं:

Public Class Foo 
    Implements ICloneable 

    Public Function Clone() As Object Implements System.ICloneable.Clone 
     Return Me.MemberwiseClone 
    End Function 
End Class 

हालांकि, यह केवल एक उथले प्रतिलिपि बना देगा, संदर्भ कॉपी जाएगा, और बार पर कन्स्ट्रक्टर का आह्वान नहीं करेगा। जब हम इस तरह से MemberwiseClone उपयोग करते हैं, हम हमेशा एक overridable विधि है कि उत्तराधिकारियों द्वारा इस्तेमाल किया जा सकता बाद क्लोन सफाई प्रदर्शन करने के लिए जोड़ें:

Public Class Foo 
    Implements ICloneable 

    Public Function Clone() As Object Implements System.ICloneable.Clone 
     Dim oObject As Foo 

     oObject = DirectCast(Me.MemberwiseClone, Foo) 
     oObject.PostCloneCleanup() 

     Return oObject 
    End Function 

    Protected Overridable Sub PostCloneCleanup() 

    End Sub 
End Class 

Public Class Bar 
    Inherits Foo 

    Public Sub New() 
     MsgBox("Test") 
    End Sub 

    Protected Overrides Sub PostCloneCleanup() 
     MsgBox("PostCloneCleanup") 
    End Sub 

End Class 

अंत में, यदि उथले नकल या प्रतिलिपि संदर्भ के साथ काम कर आप को पसंद करने के लिए नहीं है, क्रमबद्धता और अक्रमांकन BinaryFormmater का उपयोग कर: आप एक गहरी प्रतिलिपि एक सस्ता है, लेकिन बहुत प्रभावी चाल का उपयोग कर प्रदर्शन कर सकते हैं

Public Function CreateDeepCopy(Of T)(ByVal oRecord As T) As T 

    If oRecord Is Nothing Then 
     Return Nothing 
    End If 

    If Not oRecord.GetType.IsSerializable Then 
     Throw New ArgumentException(oRecord.GetType.ToString & " is not serializable") 
    End If 

    Dim oFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 

    Using oStream As IO.MemoryStream = New IO.MemoryStream 
     oFormatter.Serialize(oStream, oRecord) 
     oStream.Position = 0 
     Return DirectCast(oFormatter.Deserialize(oStream), T) 
    End Using 
End Function 

यह जरूरी है कि कक्षाओं serializable हो, लेकिन ऐसा करने के लिए आसान है।

+0

+1 लेकिन मैं वीबी की इस शैली को नापसंद करता हूं; भले ही कंपाइलर इसे जरूरी नहीं ठहराता है, आपको अपनी फ़ंक्शन कॉल को संपत्ति एक्सेस से अलग करने के लिए ब्रांड्स के साथ अर्हता प्राप्त करनी चाहिए: यानी, 'मी। गेट टाइप' आदि के बजाय 'मी। गेट टाइप() 'लिखें। –

+0

@ कोनराड रुडॉल्फ: धन्यवाद +1 मैं सहमत हूं और हमेशा उत्पादन कोड में इसका पालन करता हूं, लेकिन एक त्वरित नमूना को एक साथ फेंकने के लिए, मुझे लगा कि यह ठीक होगा। –