VB.NET 中的依赖类型

发布于 2024-12-04 17:29:56 字数 1131 浏览 1 评论 0原文

我想知道 VB.Net 4 中是否可以有依赖类型,或者是否可以基于基类构造函数的参数构造继承对象。例如,

Class BaseClass
   Sub New(type as String)
       If type = "One" then
           Me = New Child1  'Assignment to Me is syntax error, but it explains the concept...
       Else
           Me = New OtherChild
       End If
   End Sub
End Class

Class Child1
    Inherits BaseClass
...

Class OtherChild
    Inherits BaseClass
..

..
Sub Main()
   Dim c1 As New BaseClass("One")
   Dim c2 As New BaseClass("Two")
   OverloadedMethod(c1) 'Outputs One
   OverloadedMethod(c2) 'Outputs Two
End Sub

Sub OverloadedMethod(C as Class1)
   Console.Write("One")
End Sub

Sub OverloadedMethod(C as OtherClass)
   Console.Write("Two")
End Sub

编辑:有关依赖类型的说明:

依赖类型是类型它们是基于一些参数(例如标量值)构造的。这是一些(主要是函数式)编程语言(例如 Haskell)中众所周知的概念。 例如,在一种支持依赖类型的假设命令式语言中,可以编写

Matrix(3,10) A; //A is a 10x10x10 3D Matrix
Matrix(2,3)  B; //B is a 3x3 2D Matrix

A(0,0,0) = 10;
B(0,0) = -2;
B(1,1,0) = 5; // Type Error

I was wondering if it is possible to have dependent types in VB.Net 4, or alternatively, if it is possible to construct inherited objects based on the base class' constructor's parameter(s). For example,

Class BaseClass
   Sub New(type as String)
       If type = "One" then
           Me = New Child1  'Assignment to Me is syntax error, but it explains the concept...
       Else
           Me = New OtherChild
       End If
   End Sub
End Class

Class Child1
    Inherits BaseClass
...

Class OtherChild
    Inherits BaseClass
..

..
Sub Main()
   Dim c1 As New BaseClass("One")
   Dim c2 As New BaseClass("Two")
   OverloadedMethod(c1) 'Outputs One
   OverloadedMethod(c2) 'Outputs Two
End Sub

Sub OverloadedMethod(C as Class1)
   Console.Write("One")
End Sub

Sub OverloadedMethod(C as OtherClass)
   Console.Write("Two")
End Sub

EDIT : Explanations about Dependent Types :

Dependent types are types which are constructed based on some parameters(e.g. an scalar value). That is a well-known concept in some (mainly functional) programming languages(e.g. Haskell).
For example, in a hypothetical imperative language which supports dependent types, one can write:

Matrix(3,10) A; //A is a 10x10x10 3D Matrix
Matrix(2,3)  B; //B is a 3x3 2D Matrix

And then

A(0,0,0) = 10;
B(0,0) = -2;
B(1,1,0) = 5; // Type Error

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖乖公主 2024-12-11 17:29:56

编辑:考虑到您的评论,我不知道依赖类型。似乎这些还没有在任何面向对象的编程语言中实现。有研究关于将两者结合起来,但它据我所知,我们似乎还没有到实施的阶段。

目前,构造函数无法构造除其类型之外的任何其他内容构造(在您的示例中 BaseClass )。

最接近的是使用抽象工厂。看起来像这样(我保留了字符串,并将方法设为静态以进行简化,但它通常不是模式的一部分,请阅读它以获取更多详细信息):

   Class ClassFactory
      Public Shared Function GenerateBaseClassObject(type As String) As BaseClass
         If type = "One" Then
            Return New Child1  
         Else
            Return New OtherChild
         End If
      End Function
   End Class

在问题的另一部分,重载,这将只是让在对象层次结构之外定义方法变得更加困难。正如你所看到的,抽象工厂返回一个BaseClass,工厂之外没有人知道其构造的对象,它们的真实类型是什么(如果我们不考虑反射和强制转换,那么此时会感到困惑)。您应该重新设计对象层次结构以封装两种类之间的差异。

代码的完整工作重构如下所示:

MustInherit Class BaseClass
      Public MustOverride Sub Output()
   End Class

   Class Child1
      Inherits BaseClass

      Public Overrides Sub Output()
         Console.Write("One")
      End Sub
   End Class

   Class OtherChild
      Inherits BaseClass

      Public Overrides Sub Output()
         Console.Write("Two")
      End Sub
   End Class

   Class ClassFactory
      Public Shared Function GenerateBaseClassObject(type As String) As BaseClass
         If type = "One" Then
            Return New Child1
         Else
            Return New OtherChild
         End If
      End Function
   End Class

   Sub Main()
      Dim c1 As BaseClass = ClassFactory.GenerateBaseClassObject("One")
      Dim c2 As BaseClass = ClassFactory.GenerateBaseClassObject("Two")
      c1.Output()
      c2.Output()
      Console.ReadLine()
   End Sub

EDIT : Considering your comments, I wasn't aware about dependent types. It seems those are not yet implemented in any object oriented programming language. There are research about combining the two of them, bu it seems we're not yet at the step of implementation AFAIK.

At the moment, a constructor cannot construct anything else than the type it is constructing (in your example BaseClass ).

The closest you could get would be with an abstract factory. That would look like this (I kept the string, and made the method static for simplification, but it is usually not part of the pattern, read about it for more details) :

   Class ClassFactory
      Public Shared Function GenerateBaseClassObject(type As String) As BaseClass
         If type = "One" Then
            Return New Child1  
         Else
            Return New OtherChild
         End If
      End Function
   End Class

On the other part of your question, the overloading, that would just make things harder to define your methods outside of your object hierarchy. As you can see, the abstract factory return a BaseClass, and no one knows outside of the factory, and the constructed objects, what is their real type (if we don't consider reflection and casting, that would just be confusing at this point). You should rework your object hierarchy to encapsulate the differences between your two kind of classes.

A complete working refactoring of your code would look like this :

MustInherit Class BaseClass
      Public MustOverride Sub Output()
   End Class

   Class Child1
      Inherits BaseClass

      Public Overrides Sub Output()
         Console.Write("One")
      End Sub
   End Class

   Class OtherChild
      Inherits BaseClass

      Public Overrides Sub Output()
         Console.Write("Two")
      End Sub
   End Class

   Class ClassFactory
      Public Shared Function GenerateBaseClassObject(type As String) As BaseClass
         If type = "One" Then
            Return New Child1
         Else
            Return New OtherChild
         End If
      End Function
   End Class

   Sub Main()
      Dim c1 As BaseClass = ClassFactory.GenerateBaseClassObject("One")
      Dim c2 As BaseClass = ClassFactory.GenerateBaseClassObject("Two")
      c1.Output()
      c2.Output()
      Console.ReadLine()
   End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文