.net - Union or Variant type static dispatch -


i have function takes number of arguments, each of may 1 of set of types.

i can handle dynamically , throw type error if fails, in code snippet directly below rather catch these type errors @ compile time.

function specializingfunction(a) string     select case a.gettype         case gettype(integer)             return "int"         case gettype(boolean)             return "bool"         case else             return "__unknown__"  ' or throw 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 

i had hoped solve problem using dotnet generics, see final code example in question.

i happy use either: 1. open solution - client code may add further type specializations in c++ code below 2. closed solution - fixed set of allowed types, acheived algebraic data types in (e.g.) haskell or boost::variant in c++

...but interested hear answers both.

#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; } 

haskell example

data x = xint int | xbool bool  descriminator :: x -> string   descriminator (xint  a) = "int: " ++ show descriminator (xbool a) = "bool: " ++ show   lottaargs :: x -> x -> x -> x -> io () lottaargs b c d =                       putstrln $ descriminator                      putstrln $ descriminator b                      putstrln $ descriminator c                      putstrln $ descriminator d  main = lottaargs (xint 1) (xbool false) (xint 2) (xint 3) 

the solution tried 1 below, appears vb attempts instantiate function in generic form (without knowing types t1 - t4). vb therefore gives errors of form "value type 't1' cannot converted 'integer'".

function specializedfunction(a boolean) string     return "bool" end function  function specializedfunction(a integer) string     return "int" end function  sub failshorribly(of t1, t2, t3, t4)(a1 t1, a2 t2, a3 t3, a4 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 

how best can solve sort of design problem in vb? there appropriate statically-verified union or variant type?

i guess create custom type object member can constructed 1 of allowed types, not seem elegant, there must better way.

edit: solution

see answer below implementation of wrapper-object based solution

i have implemented solution custom type provides conversions in both directions in order allow me use byref arguments.

it's pretty verbose, think verbosity major design goal of vb :¬)

it's not perfect still not statically keep track of argument type , therefore provides conversions every possible contained type irrespective of it's actual type is.

i may have @ using generics on top of this.

below implementation of technique on toy int/bool example have been using question:

class allowedargs     private a_ object  ' can't declare a_ reference     '     private sub new()     end sub     '     public sub new(byref s integer)         a_ = s     end sub     '     public shared widening operator ctype(a integer) allowedargs         return new allowedargs(a)     end operator     '     public shared widening operator ctype(a allowedargs) integer         if typeof a.a_ integer             return ctype(a.a_, integer)         else             return 0         end if     end operator     '     public sub new(byref s boolean)         a_ = s     end sub     '     public shared widening operator ctype(a boolean) allowedargs         return new allowedargs(a)     end operator     '     public shared widening operator ctype(a allowedargs) boolean         if typeof a.a_ boolean             return ctype(a.a_, boolean)         else             return false         end if     end operator     '     public overrides function tostring() string         select case a_.gettype()             case gettype(integer)                 return "int: " + a_.tostring             case gettype(boolean)                 return "bool: " + a_.tostring.toupper             case else                 return "__this_should_neven_happen__"         end select     end function     '     public sub setfromstring(a string)         select case a_.gettype()             case gettype(integer)                 try                     a_ = integer.parse(a)                 catch ex exception                     a_ = 0                 end try             case gettype(boolean)                 a_ = if(a.toupper = boolean.truestring.toupper, true, false)             case else                 console.writeline("__oh_dear_this_should_never_happen__")         end select     end sub     ' end class  sub actuallyworks(byref a1 allowedargs, byref a2 allowedargs, byref a3 allowedargs, byref a4 allowedargs)     ' works fine:     console.writeline(a1.tostring())     console.writeline(a2.tostring())     console.writeline(a3.tostring())     console.writeline(a4.tostring())     ' these modifications passed correctly     a1.setfromstring("9999")     a2.setfromstring("9999")     a3.setfromstring("9999")     a4.setfromstring("9999") end sub  sub main()     dim a1 integer = 1     dim a2 integer = 2     dim a3 boolean = true     dim a4 integer = 3     actuallyworks(a1, a2, a3, a4)     console.writeline("after: " + a1.tostring)     console.writeline("after: " + a2.tostring)     console.writeline("after: " + a3.tostring)     console.writeline("after: " + a4.tostring)     console.in.readline() end sub 

Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -