访问没有实例的Kotlin委托类型

访问没有实例的Kotlin委托类型

问题描述:

我已阅读Access property delegate in Kotlin这是关于从实例访问委托的。自Kotlin 1.1以来,可以使用KProperty::getDelegate,但是这将返回委托的实例,因此需要首先使用该类的实例。访问没有实例的Kotlin委托类型

现在我想获得没有类的实例的委托类型。考虑库与自定义的委托类型CustomDelegate希望的得到被委派给的CustomDelegate实例的类的所有属性:

class Example 
{ 
    var nonDelegatedProperty = "I don't care about this property" 
    var delegatedProperty1 by lazy { "I don't care about this too" } 
    var delegatedProperty2 by CustomDelegate("I care about this one") 
} 

如何我,给我KClass<Example>,但不是Example一个实例,获取所有委托给CustomDelegate的房产?

我怎样才能,给我KClass <例>,但不 实例的实例,让下放给CustomDelegate所有属性?

根据您的需要,您可以通过两种方式来完成。

首先,你必须包括科特林,反映您的build.gradle文件依赖性:

compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51" 

在我看来,你应该使用,如果你能第一个解决方案,因为它是最清晰的并进行了优化。第二种解决方案可以处理第一种解决方案无法解决的一种情况。

首先

您可以循环的声明的属性和检查属性或委托的类型的类型是CustomDelegate

// Loop on the properties of this class. 
Example::class.declaredMemberProperties.filter { property -> 
    // If the type of field is CustomDelegate or the delegate is an instance of CustomDelegate, 
    // it will return true. 
    CustomDelegate::class.java == property.javaField?.type 
} 

这里只有一个与此解决方案的问题,你会还可以获得与CustomDelegate类型的字段,因此,给出这个例子:

class Example { 
    var nonDelegatedProperty = "I don't care about this property" 
    val delegatedProperty1 by lazy { "I don't care about this too" } 
    val delegatedProperty2 by CustomDelegate("I care about this one") 
    val customDelegate = CustomDelegate("jdo") 
} 

你会得到delegatedProperty2customDelegate。如果你只想得到delegatedProperty2,我发现了一个可怕的解决方案,如果你需要管理这个案例,你可以使用它。

如果选中的KPropertyImpl的源代码,你可以看到一个代表团是如何实现的。所以,你可以这样做:

// Loop on the properties of this class. 
Example::class.declaredMemberProperties.filter { property -> 
    // You must check in all superclasses till you find the right method. 
    property::class.allSuperclasses.find { 
     val computeField = try { 
      // Find the protected method "computeDelegateField". 
      it.declaredFunctions.find { it.name == "computeDelegateField" } ?: [email protected] false 
     } catch (t: Throwable) { 
      // Catch KotlinReflectionInternalError. 
      [email protected] false 
     } 

     // Get the delegate or null if the delegate is not present. 
     val delegateField = computeField.call(property) as? Field 
     // If the delegate was null or the type is different from CustomDelegate, it will return false. 
     CustomDelegate::class.java == delegateField?.type 
    } != null 
} 

在这种情况下,您将只能得到delegatedProperty2作为结果。

+0

使用第一种解决方案,是否可以映射委托字段和委托字段?由于我的委托属性必须全部从一个接口继承,这将使得仅仅返回'delegatedProperty2' – msrd0

+0

@ msrd0是的,你可以。你可以改变条件:CustomDelegate :: class.java == property.javaField?.type'到条件'CustomDelegate :: class.java == property.javaField?.type && property.returnType。isSubtypeOf(MyInterface的:: class.starProjectedType)' –