Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在VB.NET中,是否可以将对象的实例化限制为仅一个其他(父)对象?_Vb.net_Object_Instantiation_Restriction - Fatal编程技术网

在VB.NET中,是否可以将对象的实例化限制为仅一个其他(父)对象?

在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的要求是: 只

VB2008.NET3.5

假设我们有两个类,Order和OrderItem,它们代表某种类型的在线订购系统。OrderItem表示订单中的单行项目。一个订单可以包含多个OrderItem,其形式为(OrderItem的)列表

如果没有订单,OrderItem就不应该存在,这是有道理的。换句话说,OrderItem类不应该能够单独实例化,它应该依赖于Order类来包含它并实例化它。但是,OrderItem应该在作用域中是公共的,以便其他对象可以访问它的属性。因此,OrderItem的要求是:

  • 只能由Order类实例化

  • 必须是公共的,以便任何其他对象都可以通过Order对象访问其属性/方法。e、 g.Order.OrderItem(0.ProductID)

  • 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可以传递给其他子项和函数

  • 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