带有<A,B>和<A,B?>的KMutableProperty

时间:2019-12-22 17:48:56

标签: kotlin reflection

我想将KMutableProperty1传递给构造函数。问题是有时候我需要传递这样的属性:

class Foo(var name:String, var email:String?)

class PropertyHandler<D,F>(val prop:KMutableProperty1<D,F>)

fun test() {
   val foo = Foo("Asd", "asd@asd.com")
   val ph1 = PropertyHandler<Foo,String>(Foo::name)
   val ph2 = PropertyHandler<Foo,String>(Foo::email)
}

在这种情况下,编译器在PropertyHandler(Foo :: email)说:

Required KMutableProperty1<Foo,String?>
Found KMutableProperty1<Foo,String>

是否存在传递字符串和字符串的方法?对此吗?

我在Android中使用它,而我的Kotlin版本是1.3.50

thx 扎梅克

1 个答案:

答案 0 :(得分:1)

通过编写PropertyHandler<Foo, String>(Foo::email),您可以明确指定DFoo,而FString。因此prop应该是KMutableProperty1<Foo, String>。但是Foo::emailKMutableProperty1<Foo, String?>。并且KMutableProperty1<Foo, String>无法从KMutableProperty1<Foo, String?>分配,因为KMutableProperty1<T, R>不变于其第二个通用参数。因此,您会遇到编译错误。

以下是修复代码的几种方法:

  1. PropertyHandler<Foo, String>(Foo::email)替换为PropertyHandler<Foo, String?>(Foo::email)
  2. PropertyHandler<D, F>构造函数接受KMutableProperty1<D, in F>
    class PropertyHandler<D, F>(val prop: KMutableProperty1<D, in F>)
    
  3. 使email不可为空
    class Foo(var name: String, var email: String)
    
  4. 执行未经检查的演员表(不推荐)
    @Suppress("UNCHECKED_CAST") // explain here why it is safe
    PropertyHandler<Foo, String>(Foo::email as KMutableProperty1<Foo, String>)