复制相同名称属性的简单代码?

很长一段时间,我心中都有一个古老的问题。 当我在Spring中编写代码时,DTO,域对象有很多脏的和无用的代码。 对于语言水平,我在Java中无望,并在Kotlin中看到了一些亮点。 这是我的问题:

样式1我们通常编写以下代码(Java,C ++,C#,…)

// annot: AdminPresentation val override = FieldMetadataOverride() override.broadleafEnumeration = annot.broadleafEnumeration override.hideEnumerationIfEmpty = annot.hideEnumerationIfEmpty override.fieldComponentRenderer = annot.fieldComponentRenderer 

Sytle 2通过在Kotlin中使用T.apply()可以简化以前的代码

  override.apply { broadleafEnumeration = annot.broadleafEnumeration hideEnumerationIfEmpty = annot.hideEnumerationIfEmpty fieldComponentRenderer = annot.fieldComponentRenderer } 

Sytle 3 这样的代码甚至可以简化为这样的代码吗?

  override.copySameNamePropertiesFrom (annot) { // provide property list here broadleafEnumeration hideEnumerationIfEmpty fieldComponentRenderer } 

第一优先级要求

  1. 仅提供一次property name列表
  2. property name作为普通代码提供,以便我们可以获得IDE自动完成function。

第二优先要求

  1. 它更倾向于避免样式3的运行时成本。(例如,’reflection’可能是一种可能的实现,但它会引入成本。)
  2. 它更喜欢直接生成类似style1 / style2的代码。

不在乎

  1. Style 3的最终语法。

我是Kotlin语言的新手。 是否可以使用Kotlin来定义“Style 3”之类的东西?

编写一个5行帮助程序来执行此操作应该非常简单,甚至支持复制每个匹配的属性或仅选择一些属性。

虽然如果您编写Kotlin代码并大量使用数据类和val (不可变属性),它可能没用。 看看这个:

 fun  T.copyPropsFrom(fromObject: R, vararg props: KProperty<*>) { // only consider mutable properties val mutableProps = this::class.memberProperties.filterIsInstance>() // if source list is provided use that otherwise use all available properties val sourceProps = if (props.isEmpty()) fromObject::class.memberProperties else props.toList() // copy all matching mutableProps.forEach { targetProp -> sourceProps.find { // make sure properties have same name and compatible types it.name == targetProp.name && targetProp.returnType.isSupertypeOf(it.returnType) }?.let { matchingProp -> targetProp.setter.call(this, matchingProp.getter.call(fromObject)) } } } 

这种方法使用reflection,但它使用非常轻量级的Kotlinreflection。 我没有计时,但它应该以与手动复制属性几乎相同的速度运行。

现在给出2个课程:

 data class DataOne(val propA: String, val propB: String) data class DataTwo(var propA: String = "", var propB: String = "") 

您可以执行以下操作:

  var data2 = DataTwo() var data1 = DataOne("a", "b") println("Before") println(data1) println(data2) // this copies all matching properties data2.copyPropsFrom(data1) println("After") println(data1) println(data2) data2 = DataTwo() data1 = DataOne("a", "b") println("Before") println(data1) println(data2) // this copies only matching properties from the provided list // with complete refactoring and completion support data2.copyPropsFrom(data1, DataOne::propA) println("After") println(data1) println(data2) 

输出将是:

 Before DataOne(propA=a, propB=b) DataTwo(propA=, propB=) After DataOne(propA=a, propB=b) DataTwo(propA=a, propB=b) Before DataOne(propA=a, propB=b) DataTwo(propA=, propB=) After DataOne(propA=a, propB=b) DataTwo(propA=a, propB=)