【问题标题】:instantiate object ONLY from other class in VB.NET仅从 VB.NET 中的其他类实例化对象
【发布时间】:2014-10-02 14:59:05
【问题描述】:

我有 2 个 A 和 B 类(在 VB.NET 中)。

我想要创建 B 类对象的唯一方法是使用 A 的方法。

示例:

你可以这样做:

Dim objectA as new A
Dim objectB as B = objectA.getAobject()

但你做不到:

Dim objectB as new B

谢谢!

编辑:在“你可以做”部分,我的意思是“将 objectB 作为 B = objectA.getAobject()”

【问题讨论】:

  • 为什么不直接使用 Dim objectB = A.getAobject() ?不过,您必须关闭严格,这可能不好。
  • 实现这一点的唯一方法是将A 类放在B 内部,并让B 类有一个私有构造函数。

标签: vb.net class instantiation


【解决方案1】:

你可以在 B 中创建一个私有构造函数:

Private Sub New()

End Sub

如果没有公共构造函数,这将阻止您在除 B 本身之外的任何地方编写这样的代码:

Dim objectB as new B

但是,这要求您在 B 的某处编写类似的代码,否则您将无法在任何地方创建 B 的实例。通常,共享方法是执行此操作的地方:

Friend Shared Function Create() As B
    '...
    Return New B
End Function

注意Friend 访问修饰符。现在,如果您有一个仅包含 A 和 B 的程序集(类库项目),则只有该程序集内的代码(仅 A 和 B)才能使用该函数。在 A 中添加一个如下所示的方法:

Public Shared Function getObject() As B
   Return B.Create()
End Function

而且我们已经实现了您声明的所有目标。引用此程序集的代码将能够执行此操作:

Dim objectB as B = A.getAobject()

但将无法执行以下任何一项:

Dim objectB as new B
Dim objectB As B = B.Create()

【讨论】:

    【解决方案2】:

    如果你的调用类是 A 类型,你可以只检查 B 的构造函数

    Class B 
        Sub New ()
            ' get parent frame and calling method
            Dim frame As StackFrame = new StackFrame( 1, True )
            Dim method As MethodBase = frame.GetMethod()
    
            ' for debug purposes
            Dim methodName As String = method.DeclaringType.Name & "->" & method.Name
            Console.WriteLine(methodName)
    
            ' throw exception
            If (method.DeclaringType.Equals(typeof(A)) = False) {
                throw new Exception("Not called from class A!!")
            End If
        End Sub
    End Class
    

    【讨论】:

      【解决方案3】:

      创建一个类库类型的新项目并为A类和B类添加类似的代码

      Public Class A
          Public Function getObject() As B
              Return New B()
          End Function
      End Class
      
      Public Class B
      
          Protected Friend Sub New()
              Console.WriteLine("Constructor B called")
              Console.ReadLine()
          End Sub
      End Class
      

      现在只能从该项目中存在的内部代码调用 B 类的构造函数,而不能从其他程序集中调用

      在您的主项目中,您需要添加对这个新项目的引用并导入其命名空间。

      Module Module1
      
          Sub Main()
              Dim a1 = New A()
              ' Dim b1 = New B() 'This will not compile at all'
              Dim b2 = a1.getObject()
          End Sub
      
      End Module
      

      当然,现在您必须分发两个文件而不是一个......

      这个工作的关键是不同的程序集和关键字Protected Friend应用于B类的构造函数

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-22
        • 2010-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多