swift 3 downcast to dynamic class

796 views Asked by At

I am trying to create a couple of objects which are dependent one to each other and they mush have a method to downcast directly the concrete class of the other object. Something like this:

protocol aProt
{
    var bVar:bProt! { get set }
}

protocol bProt
{
    var aVar:aProt!  { get set }
}

class a: aProt
{
    var bVar: bProt!
    func bConcrete() -> b {
        return bVar as! b
    }
}

class b: bProt
{
    var aVar: aProt!
    func aConcrete() -> a {
        return aVar as! a
}

Now, the problem is that I want this behavior (func aConcrete(),func bConcrete()) to be inherited by the subclasses of a and b. Then I thought the perfect way of doing this was using generics, but... There's no way of doing this.

class a: aProt { var bVar: bProt! func bConcrete() -> T { return bVar as! T } }

class b: bProt
{
    var aVar: aProt!
    func aConcrete<T>() -> T {
        return aVar as! T
}

You can do it but when you have to use it you must downcast the variable anyway, so there is no way of doing it in a clean manner:

let aObject = a()
let bSubclassObject = a.bConcrete() // The compiler complains it cannot infer the class of T
let bSubclassObject = a.bConcrete() as! bSubclass // this works, but this is exactly which I wanted to avoid... :(
1

There are 1 answers

5
bubuxu On BEST ANSWER

Define the generic function and add where to T:

protocol aProt {
    var bVar: bProt! { get set }
}

protocol bProt {
    var aVar:aProt!  { get set }
}

class a: aProt {
    var bVar: bProt!
    func bConcrete<T: b>(_ type: T.Type) -> T? {
        return bVar as? T
    }
}

class b: bProt {
    var aVar: aProt!
    func aConcrete<T: a>(_ type: T.Type) -> T? {
        return aVar as? T
    }
}

class a1: a { }
class b1: b {
    var fullName: String = "new object"
}

let aObj = a()
aObj.bVar = b1()
let bObj = aObj.bConcrete(b1.self)
bObj?.fullName

According to your requirement, calls bConcrete(b1.self) might still not good enough, but at least you need to know what type of data you are expecting to return.