unity3d 如果添加了新属性,则对具有默认自动属性的单一示例进行反序列化将返回空值

utugiqy6  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(144)

我正在Unity中构建一个游戏。我有一个DataStorage父类,它是一个我序列化/反序列化以保存/加载进度的单例。
它看起来像这样:

public class DataStored
{
   // Properties

   public PlayerData Player { get; set; } = new PlayerData();
   public EnvironmentData Environ { get; set; } = new EnvironmentData();

   // Singleton

   private static DataStored current; 
   public static DataStored Current
   {
    get
    {
        if (current == null)
        {
            current = new DataStored();
        }
        return current;
    }
    set
    {
        current = value;
    }
  }
}

我以如下方式加载数据:

...
                DataStored.Current = (DataStored)bf.Deserialize(file);
...

这一切都很好。我可以发布我的游戏。但是,如果我需要添加一个新的属性到DataStored单例中,例如:

public AppSettings Settings { get; set; } = new AppSettings();

这个值最初是设置好的,但是当我加载游戏数据时,使用上面的反序列化代码行,它就被设置为null(大概是因为当我保存单例时,这个属性并不存在)。我希望单例会意识到这个属性是null,然后为这个属性创建一个新的AppSettings示例。
是否唯一的解决方法是为我添加的每个属性扩展代码,如下所示?

private PlayerStatsData stats;
public PlayerStatsData Stats
{
    get { return stats ??= new PlayerStatsData(); }
}

我猜,如果类对象是反序列化的,而不是构造一个新的,使用默认的自动属性会忽略示例化。
我问这个问题的动机是希望将我将要创建的许多新属性中的每一个属性的3行代码减少到1行代码。

igetnqfo

igetnqfo1#

您可以将以OnDeserializedAttribute属性标记的方法加入至类别,如下所示:

[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
    if (Settings == null)
    {
        Settings = new AppSettings();
    }
}

BinaryFormatter.Deserialize会自动叫用这个方法。
注意:正如其他人所说,使用BinaryFormatter时要注意,因为它已经deprecated by Microsoft

相关问题