Swift相当于C#的IsAssignableFrom

时间:2017-03-30 14:43:22

标签: swift reflection

在C#中,有两种类型,我可以说像

var stringType = typeof(string)
var intType = typeof(int)
var assignable = stringType.IsAssignableFrom(intType)

assignable的值为false,因为无法将int分配给string

有没有办法在Swift中这样做?

func isAssignable<T1, T2>(_ type1: T1.Type, from type2: T2.Type) -> Bool {
    // What's the implementation here?
}

let assignable = isAssignable(String.self, from: Int.self)

我怀疑这是目前无法实现的。

为什么我需要这个?

有些人问我为什么需要这个。我编写了一个名为Guise的依赖解析框架。每次注册都会返回唯一的Key。虽然使用Key进行分辨率实际上并不常见 - 但有更优雅的方式 - 有时它很有用,例如解析多个注册时。

在下面的代码中,查看显示if type != key.type { continue }的行。这只是比较了已注册类型的反射字符串表示。如果相反我可以直接测试可分配性,那么通用参数T就不必是进行注册的特定类型。像if !key.typeIsAssignableTo(type: T.self) { continue }这样的东西。其中typeIsAssignableToKey中的类型更重要。

此时我没有实例,也不想要一个实例。事实上,这就是重点。任何好的灾难恢复框架都应该懒散地解决,而这一点确实如此。在测试类型兼容性之前,我不想先创建实例。

public static func resolve<T, K: Sequence>(keys: K, parameter: Any = (), cached: Bool? = nil) -> [T] where K.Iterator.Element == Key {
    return lock.read {
        let type = String(reflecting: T.self)
        var resolutions = [T]()
        for (key, dependency) in registrations {
            if type != key.type { continue }
            if !keys.contains(key) { continue }
            resolutions.append(dependency.resolve(parameter: parameter, cached: cached))
        }
        return resolutions
    }
}

可能很清楚,但这是我能给出的最佳解释。

2 个答案:

答案 0 :(得分:0)

NSObject

尝试此功能
class func isSubclass(of aClass: Swift.AnyClass) -> Bool

例如:

UILabel.self.isSubclass(of: UIView.self) // true
UIView.self.isSubclass(of: UILabel.self) // false
UIView.self.isSubclass(of: UIView.self)  // true

<强> PS 即可。此方法来自NSObject类,因此仅适用于其子类型。

答案 1 :(得分:-2)

不完全是,如果你试图从另一个构造一个对象并且它不兼容,那么Swift的方式就是返回nil。 所以你可以这样做你的场景:

让assignable = Int(text:stringElement)

在这种情况下,您将拥有一个可选的Int,因为字符串可能无法转换为int。