Art*_*ero 15 groovy properties class expandometaclass property-list
我想以通用方式将对象属性复制到另一个对象(如果目标对象上存在属性,我将其从源对象复制).
我的代码使用ExpandoMetaClass工作正常,但我不喜欢这个解决方案.有没有其他方法可以做到这一点?
class User {
String name = 'Arturo'
String city = 'Madrid'
Integer age = 27
}
class AdminUser {
String name
String city
Integer age
}
def copyProperties(source, target) {
target.properties.each { key, value ->
if (source.metaClass.hasProperty(source, key) && key != 'class' && key != 'metaClass') {
target.setProperty(key, source.metaClass.getProperty(source, key))
}
}
}
def (user, adminUser) = [new User(), new AdminUser()]
assert adminUser.name == null
assert adminUser.city == null
assert adminUser.age == null
copyProperties(user, adminUser)
assert adminUser.name == 'Arturo'
assert adminUser.city == 'Madrid'
assert adminUser.age == 27
Run Code Online (Sandbox Code Playgroud)
epi*_*ian 28
我认为您的解决方案非常好,并且处于正确的轨道上.至少我觉得这很容易理解.
该解决方案的更加简洁的版本可能是......
def copyProperties(source, target) {
source.properties.each { key, value ->
if (target.hasProperty(key) && !(key in ['class', 'metaClass']))
target[key] = value
}
}
Run Code Online (Sandbox Code Playgroud)
......但它并没有根本不同.我正在遍历源属性,以便我可以使用这些值来分配给目标:).它可能不如原始解决方案强大,因为我认为如果目标对象定义了一个getAt(String)方法,它会破坏.
如果你想获得幻想,你可能会这样做:
def copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.properties*.keySet()
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
Run Code Online (Sandbox Code Playgroud)
基本上,它首先计算两个对象之间的公共属性,然后复制它们.它也有效,但我认为第一个更直接,更容易理解:)
有时少即是多.
Mic*_*d a 27
我认为最好和最明确的方法是使用InvokerHelper.setProperties方法
例:
import groovy.transform.ToString
import org.codehaus.groovy.runtime.InvokerHelper
@ToString
class User {
String name = 'Arturo'
String city = 'Madrid'
Integer age = 27
}
@ToString
class AdminUser {
String name
String city
Integer age
}
def user = new User()
def adminUser = new AdminUser()
println "before: $user $adminUser"
InvokerHelper.setProperties(adminUser, user.properties)
println "after : $user $adminUser"
Run Code Online (Sandbox Code Playgroud)
输出:
before: User(Arturo, Madrid, 27) AdminUser(null, null, null)
after : User(Arturo, Madrid, 27) AdminUser(Arturo, Madrid, 27)
Run Code Online (Sandbox Code Playgroud)
注意:如果您想要更多可读性,可以使用类别
use(InvokerHelper) {
adminUser.setProperties(user.properties)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15076 次 |
| 最近记录: |