I've encountered a problem with a method which I cannot explain. Here is some test code which shows the problem:
protocol Base {}
protocol Extended: Base {}
struct Instance:Extended {}
let anInstance = Instance()
let instanceOfBase = anInstance as Base
let instanceOfExtended = anInstance as Extended
func aMethod<T:Base>(_ instance:T) {}
aMethod(anInstance)
aMethod(instanceOfBase) // Error - Cannot invoke 'aMethod' with an argument list of type '(Base)'
aMethod(instanceOfExtended) // Error - Cannot invoke 'aMethod' with an argument list of type '(Extended)'
According to the Apple doco I've read on protocols, generics, etc. aMethod()
should accept any object that conforms to the Base
protocol. Yet it rejects both instances where I have cast them to either Base
or Extended
.
Can anyone explain this?
Also:
func aMethod2(_ instance:Base) {}
aMethod2(anInstance)
aMethod2(instanceOfBase)
aMethod2(instanceOfExtended)
Works fine so the difference seems to be whether the instance
argument is based (excuse the pun) on Base
or <T:Base>
.
For anyone questioning why I would declare a generic here. The original code looked like this:
func addViewController<T:ModelObject>(_ stack:inout [UIViewController],
object:T?,
controller:DetailsViewController<T>?,
storyboardId:String) {...
As you can see, I want to constrain several arguments to the same type. Hence the use of a generic rather than just specifying base.