.net 联合或变体类型静态分派
我有一个函数,它接受许多参数,每个参数可能是一组类型中的一个 我可以动态地处理这个问题,并在失败时抛出一个类型错误,就像下面的代码片段一样,但我更愿意在编译时捕获这些类型错误.net 联合或变体类型静态分派,.net,vb.net,.net,Vb.net,我有一个函数,它接受许多参数,每个参数可能是一组类型中的一个 我可以动态地处理这个问题,并在失败时抛出一个类型错误,就像下面的代码片段一样,但我更愿意在编译时捕获这些类型错误 函数专用化函数(a)为字符串 选择Case a.GetType Case GetType(整数) 返回“INT” Case GetType(布尔型) 返回“BOOL” 其他情况 返回“未知”或引发异常 结束选择 端函数 子系统可能失效(a1、a2、a3、a4) 控制台写入线(专用功能(a1)) 控制台写入线(专用功能(a2
函数专用化函数(a)为字符串
选择Case a.GetType
Case GetType(整数)
返回“INT”
Case GetType(布尔型)
返回“BOOL”
其他情况
返回“未知”或引发异常
结束选择
端函数
子系统可能失效(a1、a2、a3、a4)
控制台写入线(专用功能(a1))
控制台写入线(专用功能(a2))
控制台写入线(专用功能(a3))
控制台写入线(专用功能(a4))
端接头
我曾希望使用dotNET泛型来解决这个问题,请参阅本问题中的最后一个代码示例
我很乐意使用以下两种方法之一:
1.一个开放的解决方案——客户端代码可以在下面的C++代码中添加其他类型的专门化
2.封闭解决方案—一组固定的允许类型,如Haskell中的代数数据类型或C中的boost::variant++
……但我很想听到这两个问题的答案
#包括
#包括
使用名称空间std;
字符串专用函数(布尔x)
{
返回字符串(“BOOL”);
}
std::字符串专用函数(int x)
{
返回字符串(“INT”);
}
模板
空洞校正溶蚀(T1 a1、T2 a2、T3 a3、T4 a4)
{
cout我实现了一个具有自定义类型的解决方案,该解决方案提供了双向转换,以便允许我将其用于ByRef
参数
这相当冗长,但我认为冗长是VB的一个主要设计目标:
它也不是完美的,因为它仍然不能静态地跟踪参数类型,因此提供了对每个可能包含的类型的转换,而不管它的实际类型是什么
我可能会看看在上面使用泛型来帮助解决这个问题
下面是我在这个问题中使用的toy Int/Bool示例上的这项技术的实现:
类允许参数
私有a_uu作为对象“”无法将a_u声明为引用
'
私人分新
端接头
'
Public Sub New(ByRef s作为整数)
a=s
端接头
'
公共共享加宽运算符CType(作为整数)作为AllowedArgs
返回新的允许参数(a)
终端操作员
'
公共共享加宽运算符CType(a作为AllowedArgs)作为整数
如果a.a_uu的类型为整数,则
返回CType(a.a\uU4,整数)
其他的
返回0
如果结束
终端操作员
'
Public Sub New(ByRef s作为布尔值)
a=s
端接头
'
公共共享加宽运算符CType(a为布尔值)为AllowedArgs
返回新的允许参数(a)
终端操作员
'
公共共享加宽运算符CType(a作为AllowedArgs)作为布尔值
如果a.a_uu的类型是布尔值,那么
返回CType(a.a_u2;,布尔值)
其他的
返回错误
如果结束
终端操作员
'
Public将函数toString()重写为字符串
选择案例a。GetType()
Case GetType(整数)
Return“INT:+a_u.ToString
Case GetType(布尔型)
返回“BOOL:+a_u.ToString.ToUpper”
其他情况
Return“\uuuuu此情况\uuu不应发生\uuuuuuu”
结束选择
端函数
'
公共子集合FromString(作为字符串)
选择案例a。GetType()
Case GetType(整数)
尝试
a=整数。解析(a)
特例
a=0
结束尝试
Case GetType(布尔型)
a_Upper=If(a.ToUpper=Boolean.TrueString.ToUpper,True,False)
其他情况
Console.WriteLine(“哦,亲爱的,这不应该发生”)
结束选择
端接头
'
末级
子实际工作(ByRef a1作为允许参数,ByRef a2作为允许参数,ByRef a3作为允许参数,ByRef a4作为允许参数)
“这很管用:
Console.WriteLine(a1.toString())
Console.WriteLine(a2.toString())
Console.WriteLine(a3.toString())
Console.WriteLine(a4.toString())
'这些修改被正确地传回
a1.setFromString(“9999”)
a2.setFromString(“9999”)
a3.setFromString(“9999”)
a4.setFromString(“9999”)
端接头
副标题()
尺寸a1为整数=1
尺寸a2为整数=2
尺寸a3为布尔值=真
尺寸a4为整数=3
实际工程(a1、a2、a3、a4)
Console.WriteLine(“在“+a1.ToString”之后)
Console.WriteLine(“在“+a2.ToString”之后)
Console.WriteLine(“在“+a3.ToString”之后)
Console.WriteLine(“在“+a4.ToString”之后)
Console.In.ReadLine()
端接头
我实现了一个具有自定义类型的解决方案,该解决方案提供双向转换,以便允许我将其用于ByRef
参数
这相当冗长,但我认为冗长是VB的一个主要设计目标:
它也不是完美的,因为它仍然不能静态地跟踪参数类型,因此提供了对每个可能包含的类型的转换,而不管它的实际类型是什么
我可能会看看在上面使用泛型来帮助解决这个问题
下面是我在这个问题中使用的toy Int/Bool示例上的这项技术的实现:
类允许参数
私有a_uu作为对象“”无法将a_u声明为引用
'
私人分新
端接头
'
Public Sub New(ByRef s作为整数)
a=s
端接头
'
公共共享加宽运算符CType(作为整数)作为AllowedArgs
返回新的允许参数(a)
终端操作员
'
公共共享加宽运算符CType(a作为AllowedArgs)作为整数
如果a.a_uu的类型为整数,则
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)