Type check for nested generic classes in swift -


i have problem solving following use case in swift, , not sure if possible.

let's have data structure class using generics - let's call container<t>

now have list of many container can of different types t, e.g. container<a>, container<b>, container<a>, container<c>, container<c>, ...

i go through list, , each container find out "inner type" is. , cast it, if possible.

the possible types t not finite, cannot have big switch case testing each of them.

what try similar to:

if value container<???> {      <- 1. should match container type (??? stands here type)    let value = value as! container<???>   <- 2. cast specific container    ... } 

what ways possible solve 1. , 2.?

you can switch on value , conditionally cast known possible types (if case falls through: type conversion successful).

example:

class myclass : customstringconvertible {     var foo : int = 1     var description: string { return "myclass().foo = \(foo)"} }  struct container<t> {     var myvar : t }  let value1 = container<int>(myvar: 1) let value2 = container<myclass>(myvar: myclass()) let value3 = container<string>(myvar: "one") let value4 = "foobar"  let values : [any] = [value1, value2, value3, value4]  (i, value) in values.enumerate() {     switch value {     case let foo container<int>:         print("element #\(i+1) int container .myvar = \(foo.myvar)")     case let foo container<string>:         print("element #\(i+1) string container .myvar = \(foo.myvar)")     case let foo container<myclass>:         print("element #\(i+1) myclass container .myvar = \(foo.myvar)")     case _: print("element #\(i+1) of unknown type.")     } }  /* element #1 int container .myvar = 1    element #2 myclass container .myvar = myclass().foo = 1    element #3 string container .myvar = 1                        element #4 of unknown type.                                      */ 

note: posted answer saw edit addition:

"the possible types t not finite, cannot have big switch case testing each of them."

so have "infinite" number of different types might held in list of yours? in case, assume have no custom actions depending on held in container, in case don't see why need attempt down casting (since, per update in question, can always downcast of "infinite" amount of types).

"i go through list, , each container find out "inner type" is. , cast it, if possible."

this equivalent finding out container type , casting self; latter succeed , don't have purpose.

hence, remains finding out value of generic type of each container. e.g. using runtime introspection.

setup:

/* container , protocol setup */ class myclass : customstringconvertible {     var foo : int = 1     var description: string { return "myclass().foo = \(foo)"} }  protocol myuniquegenericcontainer {     func printmyvar() }  struct container<t> : myuniquegenericcontainer {     var myvar : t      // mark: myuniquegenericcontainer     func printmyvar() {         print(myvar)     } } 

example using runtime introspection find container value type , call blueprinted method printmyvar():

let value1 = container<int>(myvar: 1) let value2 = container<myclass>(myvar: myclass()) let value3 = container<string>(myvar: "one") let value4 = "foobar"  let values : [any] = [value1, value2, value3, value4]  (i, value) in values.enumerate() {     var isknown = true      switch value {     case let val myuniquegenericcontainer:         let valuemirror = mirror(reflecting: value).children.filter{ $0.label == "myvar" }         if let containermyvar = valuemirror.first?.value {             let containertype = containermyvar.dynamictype             print("element #\(i+1) type: container<\(containertype)>,",                 ".printmyvar(): ", terminator: "")             val.printmyvar()         }         else { isknown = false }     case _ : isknown = false     }     if !isknown {         print("element #\(i+1) not of container<t> type")     } } 

prints:

/* element #1 type: container<int>, .printmyvar(): 1    element #2 type: container<myclass>, .printmyvar(): myclass().foo = 1    element #3 type: container<string>, .printmyvar(): 1    element #4 not of container<t> type                                    */ 

Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -