我有一个函数,它接受多个参数,每个参数都可能是一组类型中的一个。
我可以动态地处理这个问题,如果它失败了就会抛出一个类型错误,就像下面的代码片段一样,但我更愿意在编译时捕获这些类型错误。
Function specializingFunction(a) As String
Select Case a.GetType
Case GetType(Integer)
Return "INT"
Case GetType(Boolean)
Return "BOOL"
Case Else
Return "__UNKNOWN__" ' or throw an exception
End Select
End Function
Sub mayFail(a1, a2, a3, a4)
Console.WriteLine(specializingFunction(a1))
Console.WriteLine(specializingFunction(a2))
Console.WriteLine(specializingFunction(a3))
Console.WriteLine(specializingFunction(a4))
End Sub
我曾希望使用 dotNET 泛型解决此问题,请参阅此问题中的最终代码示例。
我很乐意使用: 1. 一个开放的解决方案 - 客户端代码可以添加进一步的类型特化,如下面的 c++ 代码 2. 一个封闭的解决方案 - 一组固定的允许类型,可以通过代数数据类型来实现(例如) Haskell 或 C++ 中的 boost::variant
...但我很想听听两者的答案。
#include <string>
#include <iostream>
using namespace std;
string specializedFunction(bool x)
{
return string("BOOL");
}
std::string specializedFunction(int x)
{
return string("INT");
}
template<typename T1, typename T2, typename T3, typename T4>
void correctlyResolves(T1 a1, T2 a2, T3 a3, T4 a4)
{
cout << specializedFunction(a1) << "\n";
cout << specializedFunction(a2) << "\n";
cout << specializedFunction(a3) << "\n";
cout << specializedFunction(a4) << "\n";
}
int main()
{
correctlyResolves(1, true, 3, 4);
return 0;
}
哈斯克尔例子
data X = XInt Int | XBool Bool
descriminator :: X -> String
descriminator (XInt a) = "INT: " ++ show a
descriminator (XBool a) = "BOOL: " ++ show a
lottaArgs :: X -> X -> X -> X -> IO ()
lottaArgs a b c d = do
putStrLn $ descriminator a
putStrLn $ descriminator b
putStrLn $ descriminator c
putStrLn $ descriminator d
main = lottaArgs (XInt 1) (XBool False) (XInt 2) (XInt 3)
我尝试的解决方案是下面的解决方案,但是似乎 VB 尝试以其通用形式实例化函数(不知道类型 T1 - T4)。因此,VB 给出了“值类型 'T1' 不能转换为 'Integer'”形式的错误。
Function specializedFunction(a As Boolean) As String
Return "BOOL"
End Function
Function specializedFunction(a As Integer) As String
Return "INT"
End Function
Sub failsHorribly(Of T1, T2, T3, T4)(a1 As T1, a2 As T2, a3 As T3, a4 As T4)
Console.WriteLine(specializedFunction(a1))
Console.WriteLine(specializedFunction(a2))
Console.WriteLine(specializedFunction(a3))
Console.WriteLine(specializedFunction(a4))
End Sub
Sub Main()
failsHorribly(1, True, 3, 4)
End Sub
我怎样才能最好地在 VB 中解决这种设计问题?是否有任何适当的静态验证联合或变体类型?
Object
我想我可以用一个只能用一种允许的类型构造的成员创建一个自定义类型,但这似乎不是很优雅,必须有更好的方法。
编辑:解决方案
有关基于包装器对象的解决方案的实现,请参见下面的答案