2009-09-25 11 views
23

Nel codice Groovy sotto sostituisce i valori delle feck, arse, drink proprietà di un'istanza di Foo con quelle di un'istanza di Foo2struttura Groovy iterazione

class Foo { 
    def feck = "fe" 
    def arse = "ar" 
    def drink = "dr"  
} 

class Foo2 { 

    def feck = "fe2" 
    def arse = "ar2" 
    def drink = "dr2" 
} 


def f = new Foo() 
def f2 = new Foo2() 


["feck", "arse", "drink"].each {it -> 
    f."$it" = f2."$it" 
} 

Esiste un modo migliore per farlo ? La mia specifica preoccupazione per il codice sopra è che i nomi delle proprietà sono memorizzati come stringhe in un elenco, che verrebbe probabilmente perso quando (ad esempio) si utilizza un IDE di refactoring per modificare uno di questi nomi di proprietà.

+2

Perché no, "quella sarebbe una questione ecumenica";)? –

risposta

27

Non ho ancora trovato un buon approccio per l'esclusione delle proprietà di sola lettura (cioè metaClass, classe), ma se si desidera impostare il valore di tutte le proprietà nell'istanza di Foo che si trovano anche nell'istanza di Foo2 potresti fare quanto segue

class Foo { 
    def feck = "fe" 
    def arse = "ar" 
    def drink = "dr"  
} 

class Foo2 { 

    def feck = "fe2" 
    def arse = "ar2" 
    def drink = "dr2" 
} 


def f = new Foo() 
def f2 = new Foo2() 


f2.properties.each { prop, val -> 
    if(prop in ["metaClass","class"]) return 
    if(f.hasProperty(prop)) f[prop] = val 
} 

assert f.feck == "fe2" 
assert f.arse == "ar2" 
assert f.drink == "dr2" 
+0

puoi aiutarmi, come verificare è il tipo di proprietà? – Pushkar

4

risposta molto in ritardo ... ma che dire di prendere esclusivamente i non sinteticodeclaredFields di Foo di classe. Utilizzando il metodo:

class Foo { 
    def feck = "fe" 
    def arse = "ar" 
    def drink = "dr"  
} 

class Foo2 { 
    def feck = "fe2" 
    def arse = "ar2" 
    def drink = "dr2" 
} 


def f = new Foo() 
def f2 = new Foo2() 

Foo.declaredFields.findAll { !it.synthetic }*.name.each {it -> 
    f[it] = f2[it] 
} 

assert f.feck == "fe2" 
assert f.arse == "ar2" 
assert f.drink == "dr2" 

Se nel refactoring cambio qualcosa per esempio in Foo ma non in Foo2 poi un Exception saranno gettati da questo codice raccomandando che qualcosa non va.