2017-11-16 3 views
2

Ich habe eine Vorlage/Generika Frage.Java/Kotlin Generika

Dies ist der Code, den ich im Moment

data class RealmWatcher<T>(
     val results: RealmResults<T>, 
     val handler: (RealmResults<T>) -> Unit) 

Und und mit diesem in einem Android-Fragmente muß bestimmte Ergebnisse hören und Aktionen auf den Veränderungen auf Basis auszuführen. So können diese als Beispiel

private val realmListener = arrayOf(
      RealmWatcher<Notification>(Realm.getDefaultInstance().where(Notification::class.java).equalTo("isNew", true).findAll(), 
             { n: RealmResults<Notification> -> 
              // DO STUFF 
             }) 

ich diese während tue Start/Stopp des Fragments

override fun onResume() { 
    super.onResume() 
    // start listening and execute 
    realmListener.forEach { it.handler(it.results) } 
    realmListener.forEach { it.results.addChangeListener(it.handler) } 
} 

override fun onPause() { 
    // stop listening 
    realmListener.forEach { it.results.removeChangeListener(it.handler) } 
    super.onPause() 
} 

Es funktioniert nur, wenn ich ein Typ bin mit (wie Notification oben). Wie soll ich festlegen, dass, wenn ich verschiedene Arten in Form von

private val realmListener = arrayOf(
      RealmWatcher<Notification>(Realm.getDefaultInstance().where(Notification::class.java).equalTo("isNew", true).findAll(), 
             { n: RealmResults<Notification> -> 
             // TODO STUFF 
             }), 
      RealmWatcher<Project>(Realm.getDefaultInstance().where(Project::class.java).equalTo("isOdd", true).findAll(), 
             { n: RealmResults<Project> -> 
             // TODO STUFF 
             }) 
             ) 

verwenden möchten, wenn die Typen Mischen (Notification und Project) Ich werde einen Type mismatch Fehler. Und

wenn die definierende

private val realmListener:Array<RealmWatcher<out Any>> 

I erhalten dann auch Type mismatch Fehler

Wie kann ich das Array definieren verschiedene RealmWatcher mit verschiedenen Typen T haben?

+0

Hm, können Sie die tatsächlichen Fehler und wo sie auftreten? – Bryan

+0

Setzen Sie Varianz auf Ihre RealmWatcher-Klasse, d. H. 'Datenklasse RealmWatcher ' – SimY4

+0

@ SimY4 Das wird nicht funktionieren, da 'T' auch in' in' Position im Code verwendet wird. Siehe meine Antwort für eine funktionierende Lösung, die auch die Logik besser kapselt. – Robin

Antwort

1

Genau das zu tun, was Sie wollen, wird schwierig, weil ich keine Möglichkeit habe, dem Compiler zu sagen, dass das, was Sie tun, tatsächlich sicher ist. Das Hinzufügen von Varianz, wie einer der Kommentare vorschlägt, wird nicht funktionieren, da T sowohl in in als auch in out Positionen verwendet wird.

Sie könnten jedoch einen anderen Ansatz wählen. Erweitern Sie Ihre RealmWatcher wie folgt aus:

data class RealmWatcher<T>(
    val results: RealmResults<T>, 
    val handler: (RealmResults<T>) -> Unit 
) { 
    fun attach() { 
     handler(results) 
     results.addChangeListener(handler) 
    } 
    fun detach() { 
     results.removeChangeListener(handler) 
    } 
} 

und dann diese zwei zusätzlichen Funktionen im Lebenszyklus Rückrufe verwenden:

fun onResume() { 
    super.onResume() 
    // start listening and execute 
    realmListener.forEach { it.attach() } 
} 

fun onPause() { 
    // stop listening 
    realmListener.forEach { it.detach() } 
    super.onPause() 
} 

Dies wird tun, was Sie es wegen der gemischten generic, ohne ein Problem zu tun brauchen Parameter.