复制相同名称属性的简单代码? [英] Simple Code to Copy Same Name Properties?

查看:130
本文介绍了复制相同名称属性的简单代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很久没解决的问题.当我在Spring中编写代码时,有很多肮脏且无用的DTO域对象代码.对于语言水平,我对Java绝望了,对Kotlin也有所了解.这是我的问题:

I have an old question sustained in my mind for a long time. When I was writing code in Spring, there are lots dirty and useless code for DTO, domain objects. For language level, I am hopeless in Java and see some light in Kotlin. Here is my question:

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

Style 1 It is common for us to write following code (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()简化先前的代码

Sytle 2 Previous code can be simplified by using T.apply() in Kotlin

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

Sytle 3 这样的代码还能简化成这样的东西吗?

Sytle 3 Can such code be even simplified to something like this?

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

第一优先级要求

First Priority Requirments

  1. 仅提供一次property name列表
  2. property name作为常规代码提供,以便我们获得IDE自动完成功能.
  1. Provide property name list only one time
  2. The property name is provided as normal code, so as to we can get IDE auto complete feature.

第二优先级要求

Second Priority Requirements

  1. 最好避免使用样式3的运行时成本.(例如,反射"可能是一种可能的实现,但确实会引入成本.)
  2. 更喜欢直接生成诸如style1/style2之类的代码.

不在乎

Not care

  1. 样式3的最终语法.

我是Kotlin语言的新手.是否可以使用Kotlin定义样式3"之类的内容?

I am a novice for Kotlin language. Is it possible to use Kotlin to define somthing like 'Style 3' ?

推荐答案

编写一个5行的助手来做到这一点应该很简单,它甚至支持复制每个匹配的属性或仅复制某些属性.

It should be pretty simple to write a 5 line helper to do this which even supports copying every matching property or just a selection of properties.

尽管如果您正在编写Kotlin代码并大量利用数据类和val(不可变属性),它可能没有用.检查一下:

Although it's probably not useful if you're writing Kotlin code and heavily utilising data classes and val (immutable properties). Check it out:

fun <T : Any, R : Any> T.copyPropsFrom(fromObject: R, vararg props: KProperty<*>) {
  // only consider mutable properties
  val mutableProps = this::class.memberProperties.filterIsInstance<KMutableProperty<*>>()
  // 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))
    }
  }
}

此方法使用反射,但是使用非常轻巧的Kotlin反射.我还没有计时,但是它应该以与手动复制属性几乎相同的速度运行.

This approach uses reflection, but it uses Kotlin reflection which is very lightweight. I haven't timed anything, but it should run almost at same speed as copying properties by hand.

现在提供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=)

这篇关于复制相同名称属性的简单代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆