c# - C# 将对象绑定到 JSON 文件?
问题描述
我有一个对象:
public class BindObjectToFile
{
public int Property1 {get; set;}
public int Property2 {get; set;}
public BindObjectToFile(string BindingFilePath)
{
...
}
}
我有一个 Json 文件:
{
"Property1" : 1,
"Property2" : 2,
}
每当对象上的属性发生更改时,我希望Json 文件随之更改。
每当JsonFile中的属性发生更改时,我希望对象随之更改。
我希望 BindObjectToFile 的所有子级都能轻松继承此功能,而无需调整其属性的 getter/setter。
本质上,我想要一个感觉像是存储在文件中而不是内存中的对象。
我试过的:
- 我首先(愚蠢地)在对象中的每个 getter/setter 上序列化/反序列化整个对象:
internal int _property1;
public int Property1
{
get
{
return JsonConvert.DeserializeObject<ObjectToFile>(File.ReadAllText(JsonFilePath))._property1;
}
set
{
_property1 = value;
File.WriteAllText(JsonFilePath, JsonConvert.SerializeObject(this));
}
}
Newtonsoft.json 很棒,但是这种方法似乎是错误的,因为它迫使我为每个新孩子的每个属性重写所有样板,而没有与任何人交流我的 BindObjectToFile 类应该如何使用。
接下来,我尝试实现
INotifyPropertyChanged
仅在属性更改时保存新序列化的对象。这稍微好一点,但它仍然没有考虑文件被“BindObjectToFile”实例以外的其他东西更改的情况。我尝试创建一个也实现了 INotifyPropertyChanged 的通用 BindObjectToFile。我这样做是希望通过使用 Generic 对象,我可以在不使用继承的情况下解决这个问题,这样我就不需要找到一种方法来强迫孩子为他们的每个属性编写疯狂的 getter/setter:
public abstract class ObjectToFile<T> : INotifyPropertyChanged
{
public T _value;
public T Value
{
get
{
return JsonConvert.DeserializeObject<T>(File.ReadAllText(Path));
}
set
{
_value = value;
File.WriteAllText(Path, JsonConvert.SerializeObject(_value ));
}
}
public string JsonFilePath;
public ObjectToFile(T value, string path)
{
_value = value;
JsonFilePath = path;
}
}
但是,当子类的属性发生变化时,这仍然迫使我在子类中引发或管理 PropertyChange 事件。
而且我不想这样做——我只想要一个解决问题的父类,这样我就可以愉快地创建行为正确的子类,而无需我考虑任何这些。
这似乎很合理,对吧?
注意事项:
- 我不介意每次访问或更改属性时都重写/重新读取整个文件。
- 在我的上下文中,我不太关心速度。如果其他人打开其中一个文件,而我必须等待几百毫秒才能轮到我,那不是问题。
- 我使用的所有对象都非常简单,包含具有基本数据类型的属性。
- 我正在使用的所有对象都非常小,很少有超过五个或六个属性。
谢谢大家!
解决方案
我不相信您只能更改 json 文件的一部分,仅保存已更改的属性值。如果值的长度发生变化,则必须向上或向下移动文件的其余部分,我认为您不能这样做。因此,您每次都必须重写整个文件。如果某些代码一次更改多个属性,那真的很糟糕。我可能会添加一个.Save
方法,或者甚至添加更改跟踪,并.Commit
在完成更改时添加更改跟踪 - 因此每组更改都会写入一次文件。这也有助于与使用该对象的类的任何人进行交流。
您也不应该在每次引用属性时都读取/反序列化文件。相反,我会尝试使用FileSystemWatcher类(设置Filter
属性)来通知文件的更改。
如果观看同一文件的消费者数量是个问题,或许可以考虑使用文档/nosql 数据库,而不是自己手动操作。
推荐阅读
- docker - Docker compose:在不删除容器的情况下更改 docker compose 文件
- javascript - 使用 Leaflet 显示地理文件的长度
- amazon-web-services - 带有 Cognito 的 AWS Elasticsearch Kibana - 缺少角色
- python - 无法在 python 中使用 pyplot 和 cufflinks 模块加载正确的 3D 图像
- python - Python:从文件夹中安装轮子依赖项
- ios - 检查 Apple Watch 当前是否未连接
- java - 无法在控制器中同时添加两个功能
- java - Apache spark和scala,执行查询时出错
- php - 使用 Codeigniter 成功验证时重定向警报
- sqlalchemy - 什么是基于查询过滤器返回对象(代表数据库中的一行)的 SQLAlchemy (ORM) 命令?