在VB.NET中,是否可以将对象的实例化限制为仅一个其他(父)对象?
VB2008.NET3.5 假设我们有两个类,Order和OrderItem,它们代表某种类型的在线订购系统。OrderItem表示订单中的单行项目。一个订单可以包含多个OrderItem,其形式为(OrderItem的)列表 如果没有订单,OrderItem就不应该存在,这是有道理的。换句话说,OrderItem类不应该能够单独实例化,它应该依赖于Order类来包含它并实例化它。但是,OrderItem应该在作用域中是公共的,以便其他对象可以访问它的属性。因此,OrderItem的要求是:在VB.NET中,是否可以将对象的实例化限制为仅一个其他(父)对象?,vb.net,object,instantiation,restriction,Vb.net,Object,Instantiation,Restriction,VB2008.NET3.5 假设我们有两个类,Order和OrderItem,它们代表某种类型的在线订购系统。OrderItem表示订单中的单行项目。一个订单可以包含多个OrderItem,其形式为(OrderItem的)列表 如果没有订单,OrderItem就不应该存在,这是有道理的。换句话说,OrderItem类不应该能够单独实例化,它应该依赖于Order类来包含它并实例化它。但是,OrderItem应该在作用域中是公共的,以便其他对象可以访问它的属性。因此,OrderItem的要求是: 只
我怎样才能实现这些目标?有更好的方法吗?您可以为
OrderItem
创建一个构造函数,该构造函数接受Order
项
在此构造函数中,您可以将OrderItem
添加到Order.MyOrderItems
集合中
这将满足您的要求
Public Class OrderItem
Public Sub New(ByRef myOrder As Order)
myOrder.MyOrderItems.Add(Me)
End Sub
End Class
Order
对象来实例化OrderItem
Order.OrderItem(0.ProductID
)OrderItem
的构造函数应该是friend
(仅可访问Order
)-我说friend
,因为使用friend
可以将OrderItem
的构造函数的可见性限制在同一程序集中的类注意:此解决方案意味着Order和OrderItem位于一个库/程序集中,您正试图从另一个程序集中使用它们-否则,friend
保护将无法工作
创建OrderItem
对象的责任应仅属于Order
:
在类:公共函数CreateOrderItem(whateverParametersYouNeed)上构建一个方法,作为OrderItem
,该方法在内部实例化一个新的OrderItem
,将其添加到OrderItem
列表中,并返回对新创建项的引用
然后,您可以使用此
OrderItem
执行任何操作-它将始终属于Order
的列表。执行此操作的标准方法是将OrderItem作为接口公开,然后在Order类内的私有类中实现它。OrderItem类只能在Order类内部实例化,但可以通过公共IOrderItem接口对外公开。像这样:
Public Interface IOrderItem
ReadOnly Property ItemCode() As Integer
ReadOnly Property NumberOfItems() As Integer
ReadOnly Property Description() As String
End Interface
Public Class Order
Private m_Items As List(Of IOrderItem)
Public ReadOnly Property Items() As List(Of IOrderItem)
Get
Return m_Items
End Get
End Property
Private Class OrderItem
Implements IOrderItem
Private m_Code As Integer
Private m_NumItems As Integer
Private m_Description As String
Public Sub New(ByVal code As Integer, ByVal numItems As Integer, ByVal desc As String)
m_Code = code
m_NumItems = numItems
m_Description = desc
End Sub
Public ReadOnly Property Description() As String Implements IOrderItem.Description
Get
Return m_Description
End Get
End Property
Public ReadOnly Property ItemCode() As Integer Implements IOrderItem.ItemCode
Get
Return m_Code
End Get
End Property
Public ReadOnly Property NumberOfItems() As Integer Implements IOrderItem.NumberOfItems
Get
Return m_NumItems
End Get
End Property
End Class
End Class
你说的模块是什么意思?我的印象是,Friend修饰符将使程序集中的所有内容都可见。assembly是我应该使用的单词,而不是module。这非常接近,这是我提出的解决方案。然而,我没有正确地陈述我的第一个标准,所以我修改了它。这个方法唯一的问题是,它只需要某个地方存在一个订单,而不是一个订单进行实例化。很抱歉弄错了。@Casey-您想要一个可公开访问的类,但只能由特定的其他类实例化。据我所知,这在.NET(或大多数其他OO语言)中是不可能的。Beyond的@Stephen Martin方法的唯一方法是使用反射来检查调用堆栈,每次调用都会非常昂贵,我认为没有人会推荐它。它显然只能在运行时运行。但我会把它扔在这里的。如果新建System.Diagnostics.StackTrace().GetFrame(1.GetMethod().Name“CreateAndAddOrder”,则抛出新的ApplicationException(“无效调用方”)@Chris Hass,感谢您的输入。我认为Stephen有满足所有标准的最佳解决方案,但你们提供的备选方案也很好,这是我见过的最优雅的解决方案。我希望有某种类型的语言构造可以做到这一点,因为我经常在聚合/复合类中遇到它。这样的声明不允许任何程序集实现它认为合适的
IOrderItem
,并将这些实现传递给不知情的代码,这些代码期望它以OrderItem
的方式实现?
Public Interface IOrderItem
ReadOnly Property ItemCode() As Integer
ReadOnly Property NumberOfItems() As Integer
ReadOnly Property Description() As String
End Interface
Public Class Order
Private m_Items As List(Of IOrderItem)
Public ReadOnly Property Items() As List(Of IOrderItem)
Get
Return m_Items
End Get
End Property
Private Class OrderItem
Implements IOrderItem
Private m_Code As Integer
Private m_NumItems As Integer
Private m_Description As String
Public Sub New(ByVal code As Integer, ByVal numItems As Integer, ByVal desc As String)
m_Code = code
m_NumItems = numItems
m_Description = desc
End Sub
Public ReadOnly Property Description() As String Implements IOrderItem.Description
Get
Return m_Description
End Get
End Property
Public ReadOnly Property ItemCode() As Integer Implements IOrderItem.ItemCode
Get
Return m_Code
End Get
End Property
Public ReadOnly Property NumberOfItems() As Integer Implements IOrderItem.NumberOfItems
Get
Return m_NumItems
End Get
End Property
End Class
End Class