vb.net 专用/重载泛型

标签 vb.net generics overloading specialization

我倾向于厌恶代码中的重复,所以当我遇到唯一不同的是类型的问题时,我倾向于使用泛型。来自 C++ 背景,我发现 vb.net 的版本相当令人沮丧,我知道 C++ 有模板特化,我猜 vb.net 没有 所以我有一组例程,无论传递的类型如何,它们都执行完全相同的代码。

像这样

Public Sub decision(Of T)(ByVal a As T, ByVal b As Integer)
  If b > 10 then
    gt(a)
  Else
    lt(a)
  End If
End Sub

我只将两种类型传递给例程,字符串和整数,这些例程对字符串的处理与对整数的处理不同。

Public Sub gt(ByVal a As String)
Public Sub gt(ByVal a As Integer)

Public Sub lt(ByVal a As String)
Public Sub lt(ByVal a As Integer)

这就是我对 vb.net vs C++ 感到沮丧的地方,据我所知,C++ 会在编译时检查类型,并且只针对发送给决策的类型进行检查。但是,在 vb.net 中我得到一个错误,类型 T 无法转换为字符串或整数

Error   3   Overload resolution failed because no accessible 'gt' can be called with these arguments:
    'Public Sub gt(a As String)': Value of type 'T' cannot be converted to 'String'.
    'Public Sub gt(a As Integer)': Value of type 'T' cannot be converted to 'Integer'.

我尝试了约束 Public Sub decision(Of T As {String, Integer})(ByVal a As T, ByVal b As Integer) 但约束必须是可继承的类,因此既不是字符串也不是整数可以使用。

我的下一个解决方案是添加 gtlt 的通用版本:

Public Sub lt(Of T)(ByVal a As T)
  Debug.Fail("Not Implemented")
End Sub

Public Sub lt(Of T)(ByVal a As T)
  Debug.Fail("Not Implemented")
End Sub

嘿!没有更多的编译错误,但是唯一被调用的例程是 gtlt 的通用版本。鉴于之前的 cannot convert 错误,我想这是有道理的。我以前遇到过这个问题,那里有泛型例程的非泛型重载,当时我找不到解决方案,现在也找不到解决方案。

是否有什么我遗漏的东西会使这种类型的重载成为可能?

编辑:一个完整​​的工作示例

Module Module1
   Sub Main()

      decision(1, 5)
      decision(1, 10)
      decision("hello world", 5)
      decision("hello world", 10)

   End Sub


   Public Sub decision(Of T)(ByVal a As T, ByVal b As Integer)
      If b > 10 Then
         gt(a)
      Else
         lt(a)
      End If
   End Sub

   Public Sub gt(ByVal a As String)
      Debug.WriteLine(" gt string:  " + a)
   End Sub
   Public Sub gt(ByVal a As Integer)
      Debug.WriteLine(" gt integer: " + a.ToString)
   End Sub

   Public Sub lt(ByVal a As String)
      Debug.WriteLine(" lt string: " + a)
   End Sub
   Public Sub lt(ByVal a As Integer)
      Debug.WriteLine(" lt integer: " + a.ToString)
   End Sub

#If False Then
   Public Sub gt(Of T)(ByVal a As T)
      Debug.Fail("Not implemented")
   End Sub
   Public Sub lt(Of T)(ByVal a As T)
      Debug.Fail("Not implemented")
   End Sub
#End If
End Module

最佳答案

来自 Differences Between C++ Templates and C# Generics (同样适用于 VB .NET):

C++ allows code that might not be valid for all type parameters in the template, which is then checked for the specific type used as the type parameter. C# requires code in a class to be written in such a way that it will work with any type that satisfies the constraints. For example, in C++ it is possible to write a function that uses the arithmetic operators + and - on objects of the type parameter, which will produce an error at the time of instantiation of the template with a type that does not support these operators. C# disallows this; the only language constructs allowed are those that can be deduced from the constraints.

我无法使用 .NET 泛型解决您的问题。但是您可以通过使用 lambda 和闭包来避免重复逻辑,我也认为这是在 .NET 中执行此操作的更自然的方法:

Public Sub Decision(ByVal a As String, ByVal b As Integer)
    Decision(b, Sub() gt(a), Sub() lt(a))
End Sub

Public Sub Decision(ByVal a As Integer, ByVal b As Integer)
    Decision(b, Sub() gt(a), Sub() lt(a))
End Sub

Private Sub decision(ByVal b As Integer, ByVal gt As Action, ByVal lt As Action)
    If b > 10 Then
        gt()
    Else
        lt()
    End If
End Sub

Public Sub gt(ByVal a As String)
    Debug.WriteLine(" gt string:  " + a)
End Sub
Public Sub gt(ByVal a As Integer)
    Debug.WriteLine(" gt integer: " + a.ToString)
End Sub

Public Sub lt(ByVal a As String)
    Debug.WriteLine(" lt string: " + a)
End Sub
Public Sub lt(ByVal a As Integer)
    Debug.WriteLine(" lt integer: " + a.ToString)
End Sub 

关于vb.net 专用/重载泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9023915/

相关文章:

c++ - 运算符 () 重载模板 C++

c++ - 重载虚函数集的部分继承

java - 使用许多可选参数有效地重载函数

asp.net - 无论如何要在上传前确定文件大小?

vb.net - 内存不足,无法继续执行程序

c# - 如何将符号(英镑、欧元、版权)插入文本框

vb.net - 范围变量名称不能与 'Object' 类的成员名称匹配。使用 Linq 查询 DataGridView 时

php - GOTO 是一个好习惯吗? (在这个 php 特殊情况下?)

java - 带有参数化类的泛型类型的反射查找方法

java - java泛型和继承相关的编译错误