我已经问了一个问题here我基本上要求将基类的实例转换为子类(或者使用基类实例创建的子类的新实例&#39) ;属性)。结论似乎是,最好的方法是手动分配我需要在基类的构造函数中传输的每个属性。
虽然在某些情况下这是可行的,但当传输的属性很多,或者基类可能发生变化时,肯定不会 - 每次向基类添加属性时,都需要更改构造函数所以这个解决方案也不够优雅。
我在网上搜索过,看不出为什么没有实现这种类型转换的原因。到目前为止,我所看到的论点描述了这种操作“没有任何意义”。 (从汽车上制作一辆小型货车就是我所看到的类比),质疑如何处理子类中的非继承变量,或声称必须有一些更好的解决方案来实现。
据我所知,这项操作并不需要“理解”。只要它有用,所以这不是一个很好的理由。添加更多属性(可能是方法/覆盖它们)将实例更改为子类有什么不对?在非继承变量的情况下,可以简单地通过允许这种类型转换来解决,只有构造函数被添加到子类中或者只是简单地将它们设置为它们的默认值。毕竟,构造函数通常会调用MyBase.New(...)
。使用基础构造函数(实质上是创建基础的新实例)和使用已经初始化的实例之间的区别是什么?最后,我不认为第三个论点是合理的 - 有时候所有其他解决方案都不够优雅。
最后,是否还有其他理由说明为什么不允许进行这种投射,是否有一种优雅的方法可以避免这种情况?
编辑:
由于我对这个话题了解不多,我想我的意思是说“转换”#39;而不是“演员”。我还将添加一个示例来说明我尝试成功的原因。只有在子类初始化时才允许转换:
Class BaseClass
Dim x as Integer
Dim y as Integer
End Class
Class Subclass1 : Inherits BaseClass
Dim z as Integer
Sub New(Byval value As Integer)
'Standard initialisation method
MyBase.New()
z = value
End Sub
Sub New(Byval value As Integer, Byval baseInstance As BaseClass)
'Type conversion from base class to subclass
baseInstance.passAllproperties()
'This assigns all properties of baseInstance belonging to BaseClass to Me.
'Properties not in BaseClass (eg. if baseInstance is Subclass2) are ignored.
z = value
End Sub
End Class
Class Subclass2 : Inherits BaseClass
Dim v As Integer
End Class
答案 0 :(得分:1)
使用System.Reflection
迭代基类的属性和字段,并将它们应用于派生类。此示例包含单个公共属性和单个公共字段,但也可以使用多个私有/受保护属性和字段。您可以将整个示例粘贴到新的控制台应用程序中进行测试。
Imports System.Reflection
Module Module1
Sub Main()
Dim p As New Parent
p.Property1 = "abc"
p.Field1 = "def"
Dim c = New Child(p)
Console.WriteLine("Property1 = ""{0}"", Field1 = ""{1}""", c.Property1, c.Field1)
Console.ReadLine()
End Sub
Class Parent
Public Property Property1 As String = "not set"
Public Property Field1 As String = "not set"
End Class
Class Child
Inherits Parent
Public Sub New(myParent As Parent)
Dim fieldInfo = GetType(Parent).GetFields(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each field In fieldInfo
field.SetValue(Me, field.GetValue(myParent))
Next
Dim propertyInfo = GetType(Parent).GetProperties(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each prop In propertyInfo
prop.SetValue(Me, prop.GetValue(myParent))
Next
End Sub
End Class
End Module
输出:
Property1 =" abc",Field1 =" def"
此解决方案是自动化的,因此在添加或删除基类中的属性和字段时,您不需要更改任何内容。