如何监控对象属性的变化?

时间:2016-09-27 12:50:23

标签: c#

我写了一个代码,它读取了包含我的应用程序的所有配置的json中的所有项目。在此代码中,我有一个名为public static SuperModel obj { get { string json = File.ReadAllText(SettingsConfig.ConfigFilePath); var jsonObj = JsonConvert.DeserializeObject<SuperModel>(json); return jsonObj; } } 的属性:

SuperModel

Settings.obj.GeneralSettings.Language = "english"; Settings.Save(); 是包含其他类实例的类模型。 我想要实现的是更新json值,然后调用另一个应该用新json覆盖文件的方法,如下所示:

obj

但我有问题,如何监控Language上的更改,例如在这种情况下,我已更新GeneralSettings的{​​{1}}属性 - &GT; SuperModel类,是否可以使用覆盖文件的Save()方法存储更新的对象? 我从未遇到类似的情况。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

您尝试解决的主要问题不是关于如何检测更改(CodeCaster在answer linked中对此进行了详细描述)。这里的问题是你的设计存在很大缺陷。

您实际上滥用属性来执行方法应该执行的操作。您的属性表现为数据的生成器,每次调用时都会返回一个新实例(尽管从值的角度来看它们是相同的)。您永远不会将反序列化的设置永久存储在任何位置,因此实现Save()方法没有直接的方法也就不足为奇了。

解密您的代码并实现这样的使用模式:

Settings.LoadFromConfig();

… do whateever changes you need here …
Settings.MyConfig.GeneralSettings.Language = "english";

Settings.SaveToConfig();

LoadFromConfigSaveFromConfig方法应该使用SuperModel属性,可以像这样声明:

public SuperModel MyConfig { get; private set; }

(私有setter确保除Settings类之外的任何人都可以创建新的配置实例。)

LoadFromConfigSaveFromConfig的实际实施对您来说应该很容易。

旁注:您的Settings类似乎是静态的。虽然它可能有意义,但通常使用实例工作通常会更好,尽管它是singleton

答案 1 :(得分:1)

你问错了问题。您不希望&#34;检测对象更新&#34;,您希望在当前return语句中保留对超出范围的本地变量的引用。

为此,只需加载一次设置文件,例如在静态构造函数中:

private static SuperModel _settingsObject;

static Settings
{
    string json = File.ReadAllText(SettingsConfig.ConfigFilePath);
    var jsonObj = JsonConvert.DeserializeObject<SuperModel>(json);
    _settingsObject = jsonObj;
}

然后当调用者获得设置对象时,只需返回加载的对象:

public static SuperModel obj
{
    get
    {
        return _settingsObject;
    }
}

现在,任何更改SuperModel返回的Settings.obj实例的调用者都会直接修改Settings类已知的实例。因此Save()方法保存修改后的实例:

public static void Save()
{
    string json = JsonConvert.SerializeObject(_settingsObject);
    File.WriteAllText(SettingsConfig.ConfigFilePath, json);
}

另外,请查看.NET的命名准则。 &#34;物镜&#34;并不是一个有用的标识符。

答案 2 :(得分:0)

在读取对象时,假设您有多个嵌套链,您可以对对象属性进行哈希并将其存储在某处(例如 InitialHash 属性)。

每当您想要检查更改时,可以重新对象对象属性并将其与 InitialHash 进行比较。这只会告诉您对象属性已更改的信息,而不是更改的确切内容。