Reputation: 368
I'm trying to read a class from a String and pass its type to a generic function. But it seems like there's no way to achieve this:
protocol Person { ... }
class Student: Person { ... }
class Teacher: Person { ... }
func foo<SomePerson: Person>(param: String, type: SomePerson.Type) { ... }
// Get class from string and pass class type to foo()
let someClass = NSClassFromString("MyApp.Teacher")
foo("someParam", type: someClass.dynamicType)
Trying this I'm getting an error:
Cannot invoke 'foo' with an argument list of type '(String, type: AnyClass.Type)
Is it actually possible to obtain the 'real' type 'Teacher' instead of the generic type 'AnyClass' and pass it to foo()? The classes are read on runtime from a file - so using hard class names when calling foo() is not possible.
Thanks for any advice!
Upvotes: 2
Views: 610
Reputation: 57114
If Person
is a class as the original question was written:
Since you are making the life for the compiler considerably harder that it needs to be you have to help him a bit. You have to make sure the type is correct before calling the function:
if let actualType = someClass as? Person.Type {
foo("someParam", type: actualType)
} else {
// error handling here
}
Which yields the desired working code:
If Person
is a protocol:
You are going to have a bad day. The above solution will not work. As far as I can remember your only option is to check for every possible subclass:
if let actualType = someClass as? Student.Type {
foo("someParam", type: actualType)
} else if let actualType = someClass as? Teacher.Type {
foo("someParam", type: actualType)
}
// etc.
Upvotes: 3