I just encountered a strange behavior in swift's inheritance handling, when it comes to polymorphism and dynamic types. The following code shows the problem I encounter, which basically is: The dynamic type is recognized correctly (printed by print("type(of: self) = \(classType)")), but the generic function testGeneric uses the wrong type.
class Global {
static func testGeneric<T: TestSuperClass>(of type: T.Type) {
print("T.Type = \(T.self)")
}
}
class TestSuperClass {
func run() {
let classType = type(of: self)
print("type(of: self) = \(classType)")
Global.testGeneric(of: classType)
}
}
class TestClass: TestSuperClass {
}
class TestClass2: TestSuperClass {
override func run() {
let classType = type(of: self)
print("type(of: self) = \(classType)")
Global.testGeneric(of: classType)
}
}
let testClass = TestClass()
let testClass2 = TestClass2()
testClass.run()
testClass2.run()
the printed output is
type(of: self) = TestClass
T.Type = TestSuperClass
type(of: self) = TestClass2
T.Type = TestClass2
So basically when calling testClass.run(), type(of: self) yields TestClass, which I would expect. The problem then is that the generic function testGeneric, which is called immediately afterwards, somehow does not work with type TestClass, but uses TestSuperClass instead.
What I personally would expect is
type(of: self) = TestClass
T.Type = TestClass
type(of: self) = TestClass2
T.Type = TestClass2
i.e., the generic function testGeneric using the type TestClass instead of TestSuperClass when called via testClass.run().
Questions:
- Do you have an explanation for that?
- How can I obtain the behavior I had in mind?