问题描述
在初始化属性 y 之后,我想在我的类 init 块中调用一些代码。我已经用 this::y.isInitialized
... 试过了,但这里的问题是在创建类时,属性没有初始化(它在运行时得到)。
示例类
class Example {
lateinit var y: String // this gets initialized after the creation of the fragment at a later time
init {
if(this::y.isInitialized) {
doStuff()
}
}
}
Szenario
val testObject = Example()
testObject.y = "START INIT CODE" // here it should execute the init block
这甚至可能吗?或者我应该在确保 y
已初始化后使用函数调用更改 init 块?
解决方法
public class User
{
// Add just the properties you care about
public string Id { get; private set; }
public string UserName { get; private set; }
public string DisplayName { get; private set; }
public string Color { get; private set; }
public string Email { get; private set; }
// Make the default constructor private so instances of this
// class can only be created from one of our static methods
private User() { }
public static User FromTwitch(TwitchUser twitchUser)
{
return new User
{
Id = twitchUser.Id,Color = twitchUser.Color,DisplayName = twitchUser.DisplayName,UserName = twitchUser.UserName
};
}
public static User FromDiscord(DiscordUser discordUser)
{
return new User
{
Email = discordUser.Email,UserName = discordUser.Username
};
}
}
块专门用于实例化时调用的代码,因此它不适用于 init
的东西。
我还必须提到,在我看来,公共 lateinit
是一种巨大的代码气味。没有办法强制外部类在编译时适当地处理它。 lateinit var
适用于仅在某些构建后事件之后才可用(可见)的属性。
假设我们不关心设计问题,您可以解决的一种方法是使用第二个可为空的支持属性。
lateinit
,
你可以这样做:
class Example {
var y: String = "UNINITIALIZED"
set(value) {
if (field == "UNINITIALIZED") doStuff(value)
field = value
}
fun doStuff(y: String) {...}
}
或者如果你需要修改初始值:
class Example {
var y: String = "UNINITIALIZED"
set(value) {
field = if (field == "UNINITIALIZED") doStuff(value) else value
}
fun doStuff(y: String): String {...}
}
,
您可以为此使用可观察的属性委托。举个例子:
import kotlin.properties.Delegates
class Example {
var y: Int? by Delegates.observable(initialValue = null) { _,oldValue,_ ->
if (oldValue == null) {
doStuff()
}
}
private fun doStuff() {}
}
如果您需要更复杂的逻辑,比如只允许分配一次属性,您可能需要实现自己的 property delegate,类似于所建议的。