Data BindingでDelegates.observableを使う際に非nullの初期値を強制されたくない件

Data Binding Library で notifyPropertyChanged を利用する際、普通にやると下記のように非 null の初期値が強制されてしまう。

class MyModel : BaseObservable() {
    @get:Bindable
    var myText: String by Delegates.observable("") { _, _, _ -> notifyPropertyChanged(BR.myText) }
}

しかし、lazy のように get 時には非 null だが初期値は null にしたいというケースがある。

でも、下記のようにできるとラクチンっすね。

class MyModel : BaseObservable() {
    @get:Bindable
    var myText: String by dataBindingObservable(BR.myText)
}

ということで、以下のようなコードで対応する。

// 上記から dataBindingObservable(BR.myText) って呼ばれるやつ。
fun <T> BaseObservable.dataBindingObservable(brId: Int): ReadWriteProperty<Any?, T> = lazyObservable { _, _, _ -> notifyPropertyChanged(brId) }

/**
 * @see kotlin.properties.Delegates.observable
 */
inline fun <T> lazyObservable(crossinline onChange: (property: KProperty<*>, oldValue: T?, newValue: T) -> Unit):
        ReadWriteProperty<Any?, T> = object : LazyObservableProperty<T>() {
    override fun afterChange(property: KProperty<*>, oldValue: T?, newValue: T) = onChange(property, oldValue, newValue)
}

/**
 * @see kotlin.properties.ObservableProperty
 */
abstract class LazyObservableProperty<T> : ReadWriteProperty<Any?, T> {
    private var value: T? = null

    protected open fun beforeChange(property: KProperty<*>, oldValue: T?, newValue: T): Boolean = true

    protected open fun afterChange(property: KProperty<*>, oldValue: T?, newValue: T) {}

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        val oldValue = this.value
        if (!beforeChange(property, oldValue, value)) {
            return
        }
        this.value = value
        afterChange(property, oldValue, value)
    }
}

おまけ。

// notifyChange() を使いたい場合
fun <T> BaseObservable.dataBindingObservable(): ReadWriteProperty<Any?, T> = lazyObservable { _, _, _ -> notifyChange() }

// 初期値と brId を指定したい場合
fun <T> BaseObservable.dataBindingObservable(initialValue: T, brId: Int): ReadWriteProperty<Any?, T> = Delegates.observable(initialValue) { _, _, _ -> notifyPropertyChanged(brId) }

// 初期値を指定して notifyChange() を使いたい場合
fun <T> BaseObservable.dataBindingObservable(initialValue: T): ReadWriteProperty<Any?, T> = Delegates.observable(initialValue) { _, _, _ -> notifyChange() }