目录
一、简介
在上位机开发中,经常会有数据需要长期保存,比如常见的配置文件,即使软件关闭,下次重新打开也不会受到影响,但也有些数据,不适合写到配置文件中,比如软件的操作记录,特殊的一些全局变量等,因此我写了一个简单的本地存储系统,将数据写到 Json 文件中,并让其和缓存中的变量保持一致。
我们需要实现下面的功能:
1.json 文件如果不存在,自动创建
2.对应路径文件夹如果不存在,自动创建
3.软件运行后,json 文件的数据要自动加载到变量中
4.软件中进行了添加,删除,任何数据改变都要同步到 json 文件中
5.保存数据的类型,目前设置为两种,键值对和数组
6.提供大部分场景对应的接口
二、实现效果
新建一个 .Net Framework 4.8 控制台项目,项目名随意,写代码之前,先添加一个插件

简单版(推荐)
简单版的用下面的代码就行了,简单而稳定
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// Json 配置文件管理
/// </summary>
internal class JsonConfigManager
{
#region 字段
//json 文件的路径
private string JsonPath = string.Empty;
//数据列表
private Dictionary<string, JToken> DataDictionary = new Dictionary<string, JToken>();
//锁
private object locks = new object();
#endregion
#region 数据处理
/// <summary>
/// 读取配置文件
/// </summary>
public void ReadConfig()
{
lock (locks)
{
if (string.IsNullOrEmpty(JsonPath))
{
Console.WriteLine("请在构造函数传入正确的文件路径");
return;
}
string json = null;
Dictionary<string, JToken> data = null;
try
{
json = File.ReadAllText(JsonPath);
data = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(json);
}
catch (Exception ex)
{
Console.WriteLine("[配置文件管理]读取配置文件错误:{0}", ex.Message);
return;
}
if (data != null)
DataDictionary = data;
else
Console.WriteLine("[配置文件管理]未读取到配置文件的值");
}
}
/// <summary>
/// 获取配置文件 key 的值
/// </summary>
/// <typeparam name="T">key的类型</typeparam>
/// <param name="key">key</param>
/// <returns>p1.是否成功,p2.key的值,p3.错误</returns>
public (bool, T, string) Get<T>(string key)
{
if (string.IsNullOrEmpty(JsonPath))
return (false, default(T), "请在构造函数传入正确的文件路径");
if (string.IsNullOrEmpty(key))
return (false, default(T), "参数 key 不能为空");
lock (locks)
{
if (!DataDictionary.TryGetValue(key, out JToken token))
return (false, default(T), $"未找到 {key} 的值");
T value;
try
{
value = token.ToObject<T>();
}
catch (Exception ex)
{
return (false, default(T), $"转换值错误:{ex.Message}");
}
return (true, value, null);
}
}
/// <summary>
/// 获取配置文件 key 的值,若 key 不存在则保存
/// </summary>
/// <typeparam name="T">key的类型</typeparam>
/// <param name="key">key</param>
/// <param name="value">key的值,如key不存在则保存当前键值对</param>
/// <returnsp1.是否成功,p2.key的值,p3.错误</returns>
public (bool, T, string) GetAndSave<T>(string key, T value)
{
if (string.IsNullOrEmpty(JsonPath))
return (false, default(T), "请在构造函数传入正确的文件路径");
if (string.IsNullOrEmpty(key))
return (false, default(T), "参数 key 不能为空");
if (value == null)
return (false, default(T), "参数 value 不能为空");
lock (locks)
{
if (!DataDictionary.TryGetValue(key, out JToken token))
{
var tuple = Set(key, value);
if (tuple.Item1)
return (true, value, null);
else
return (false, default(T), tuple.Item2);
}
T value2;
try
{
value2 = token.ToObject<T>();
}
catch (Exception ex)
{
return (false, default(T), $"转换值错误:{ex.Message}");
}
return (true, value2, null);
}
}
/// <summary>
/// 设置配置文件的值
/// </summary>
/// <typeparam name="T">key的类型</typeparam>
/// <param name="key">key</param>
/// <param name="value">key的值</param>
/// <returns>p1.是否成功,p2.错误</returns>
public (bool, string) Set<T>(string key, T value)
{
if (string.IsNullOrEmpty(JsonPath))
return (false, "请在构造函数传入正确的文件路径");
if (string.IsNullOrEmpty(key))
return (false, "参数 key 不能为空");
if (value == null)
return (false, "参数 value 不能为空");
lock (locks)
{
try
{
DataDictionary[key] = value != null ? JToken.FromObject(value) : JValue.CreateNull();
string json = JsonConvert.SerializeObject(DataDictionary, Formatting.Indented);
File.WriteAllText(JsonPath, json);
return (true, null);
}
catch (Exception ex)
{
return (false, $"设置值错误:{ex.Message}");
}
}
}
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
/// <param name="jsonPath">配置文件的完整路径</param>
public JsonConfigManager(string jsonPath)
{
if (string.IsNullOrEmpty(jsonPath))
{
Console.WriteLine("[配置文件管理]参数 jsonPath 不能为空");
return;
}
if (!File.Exists(jsonPath))
{
Console.WriteLine("[配置文件管理]参数 jsonPath 文件路径不存在");
return;
}
JsonPath = jsonPath;
ReadConfig();
}
#endregion
}
这个怎么用我就不展示了,就几个方法,都是基础的东西,或者你直接复制代码问 AI 应该也是没问题的。
旧版(仅参考)
下面的代码是之前写的旧版的,功能虽然多一些,但整体没那么优雅,不知道有没有隐形的 bug
添加一个类 LocalStorage.cs
代码:
using LogManager;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// 简单的本地数据读写系统
/// </summary>
internal sealed class LocalStorage
{
#region 字段
//json 文件的路径
private string JsonPath = string.Empty;
//数据列表
private Dictionary<string, JToken> DataDictionary = new Dictionary<string, JToken>();
//锁
private readonly object locks = new object();
#endregion
#region 构造函数
public LocalStorage(string path)
{
if (string.IsNullOrEmpty(path))
{
Debug.Error("参数 path 不能为空");
return;
}
var suffix = Path.GetExtension(path);
if (string.IsNullOrEmpty(suffix))
{
Debug.Error("[LocalStorage]路径必须包含文件名和扩展名");
return;
}
JsonPath = path;
ReadConfigData();
}
/// <summary>
/// 读取配置文件
/// </summary>
public void ReadConfigData()
{
lock (locks)
{
try
{
EnsureFileExists();
string json = File.ReadAllText(JsonPath);
DataDictionary = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(json)
?? new Dictionary<string, JToken>();
}
catch (Exception ex)
{
Debug.Log($"[LocalStorage]配置文件读取失败:{ex.Message}");
DataDictionary = new Dictionary<string, JToken>();
}
}
}
#endregion
#region 设置键值对
/// <summary>
/// 设置键值对的值,用来存储数字,重复设置会覆盖
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <param name="value">值</param>
public void SetValueNumber<T>(string key, T value) where T : struct
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(value);
SaveToLocal();
}
}
/// <summary>
/// 设置键值对的值,用来存储字符串,重复设置会覆盖
/// </summary>
/// <param name="key">key</param>
public void SetValueString(string key, string value)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
if (string.IsNullOrEmpty(value))
{
Debug.Warning("[LocalStorage]参数 value 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(value);
SaveToLocal();
}
}
/// <summary>
/// 设置键值对的值,用来存储类,重复设置会覆盖
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetValueClass<T>(string key, T value) where T : class, IAllowedType
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(value);
SaveToLocal();
}
}
#endregion
#region 获取键值对
/// <summary>
/// 获取键值对
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <returns></returns>
public T GetValue<T>(string key)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return default(T);
}
lock (locks)
{
try
{
if (DataDictionary.TryGetValue(key, out var token))
return token.ToObject<T>();
else
return default(T);
}
catch (Exception)
{
return default(T);
}
}
}
/// <summary>
/// 获取键值对
/// </summary>
/// <param name="key">key</param>
/// <param name="type">反射类型</param>
/// <returns></returns>
public object GetValue(string key, Type type)
{
if (type == null)
{
Debug.Warning("[LocalStorage]参数 type 不能为空");
return null;
}
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return null;
}
lock (locks)
{
try
{
if (DataDictionary.ContainsKey(key))
return DataDictionary[key].ToObject(type);
else
return null;
}
catch (Exception)
{
return null;
}
}
}
/// <summary>
/// 尝试获取键值对
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <param name="value">值</param>
/// <returns></returns>
public bool TryGetValue<T>(string key, out T value)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
value = default;
return false;
}
lock (locks)
{
try
{
if (DataDictionary.TryGetValue(key, out var token))
{
value = token.ToObject<T>();
return true;
}
}
catch (Exception) { }
value = default;
return false;
}
}
/// <summary>
/// 尝试获取键值对,如果存在 key,则返回它的值,
/// 如果没有找到 key,返回参数 value 的值,并将 value 的值保存到本地
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public T TryGetValueAndSave<T>(string key, T value) where T : struct
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return default(T);
}
lock (locks)
{
try
{
if (!DataDictionary.TryGetValue(key, out var token))
{
SetValueNumber(key, value);
return value;
}
return token.ToObject<T>();
}
catch (Exception)
{
return default(T);
}
}
}
/// <summary>
/// 尝试获取键值对,如果无此 key 将参数 value 保存到本地,
/// 如果参数 value 不在 min、max 范围内,会返回 value,但不会保存。
/// 如果读取本地的 value 不在 min、max 范围内,则使用参数的键值对保存覆盖,并返回 value 的值。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <param name="value">默认值</param>
/// <param name="min">参数的最小值</param>
/// <param name="max">参数的最大值</param>
/// <returns></returns>
public (bool, T) TryGetValueAndSave<T>(string key, T value, T min, T max) where T : struct, IComparable<T>
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return (false, value);
}
if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
{
Debug.Warning("[LocalStorage]] value 的值 必须在 max、min 范围内");
return (false, value);
}
lock (locks)
{
try
{
//如果获取成功
if (DataDictionary.TryGetValue(key, out var token))
{
T _value = token.ToObject<T>();
//值相同
if (_value.Equals(value))
return (true, _value);
//值超出了范围
if (_value.CompareTo(min) < 0 || _value.CompareTo(max) > 0)
{
SetValueNumber(key, value);
return (true, value);
}
//值在范围内
return (true, _value);
}
SetValueNumber(key, value);
return (false, value);
}
catch (Exception)
{
return (false, value);
}
}
}
#endregion
#region 设置列表
/// <summary>
/// 设置列表的值,用于值类型,会替换整个 List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <param name="list">列表</param>
public void SetListNumber<T>(string key, List<T> list) where T : struct
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(list);
SaveToLocal();
}
}
/// <summary>
/// 设置列表的值,用于字符串,会替换整个 List
/// </summary>
/// <param name="key">key</param>
/// <param name="list">列表</param>
public void SetListString(string key, List<string> list)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(list);
SaveToLocal();
}
}
/// <summary>
/// 设置列表的值,用于 class 类型,会替换整个 List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="list"></param>
public void SetListClass<T>(string key, List<T> list) where T : class, IAllowedType
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
DataDictionary[key] = JToken.FromObject(list);
SaveToLocal();
}
}
#endregion
#region 获取列表
/// <summary>
/// 获取列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">key</param>
/// <returns></returns>
public List<T> GetList<T>(string key)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return null;
}
lock (locks)
{
try
{
if (DataDictionary.TryGetValue(key, out var token) && token != null)
{
var result = token.ToObject<List<T>>();
return result;
}
return null;
}
catch (Exception)
{
return null;
}
}
}
/// <summary>
/// 尝试获取列表,如果获取失败则返回 false,value 值则为空
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool TryGetList<T>(string key, out T value)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
value = default(T);
return false;
}
lock (locks)
{
try
{
if (DataDictionary.TryGetValue(key, out var token))
{
value = token.ToObject<T>();
return true;
}
value = default;
return false;
}
catch (Exception)
{
value = default;
return false;
}
}
}
#endregion
#region 向列表追加数据
/// <summary>
/// 向列表中追加数据,主要用于值类型,不会检测 List 元素容是否重复
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
public void ListAddNumber<T>(string key, T value) where T : struct
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
if (DataDictionary.TryGetValue(key, out var token))
{
if (token is JArray array)
{
array.Add(value);
}
}
else
{
var newArray = new JArray { JToken.FromObject(value) };
DataDictionary[key] = newArray;
}
SaveToLocal();
}
}
/// <summary>
/// 向列表中追加数据,主要用于字符串类型,不会检测 List 元素容是否重复
/// </summary>
/// <param name="key">key</param>
/// <param name="value">要添加的元素</param>
public void ListAddString(string key, string value)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
if (DataDictionary.TryGetValue(key, out var token))
{
if (token is JArray array)
{
array.Add(value);
}
}
else
{
var newArray = new JArray { JToken.FromObject(value) };
DataDictionary[key] = newArray;
}
SaveToLocal();
}
}
/// <summary>
/// 向列表中追加数据,主要用于 class 类型,不会检测 List 元素容是否重复
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
public void ListAddClass<T>(string key, T value) where T : class, IAllowedType
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
if (DataDictionary.TryGetValue(key, out var token))
{
if (token is JArray array)
{
// 如果已经是 JArray,直接添加新对象
array.Add(JToken.FromObject(value));
}
else
{
// 如果不是 JArray,创建一个新的 JArray 存储
var newArray = new JArray { JToken.FromObject(value) };
DataDictionary[key] = newArray;
}
}
else
{
// 如果没有找到 key 对应的数据,创建一个新的 JArray 存储
var newArray = new JArray { JToken.FromObject(value) };
DataDictionary[key] = newArray;
}
SaveToLocal();
}
}
#endregion
#region 删除数据
/// <summary>
/// 删除对应 key 的所有数据
/// </summary>
/// <param name="key">key</param>
public void Remove(string key)
{
if (string.IsNullOrEmpty(key))
{
Debug.Warning("[LocalStorage]参数 key 不能为空");
return;
}
lock (locks)
{
if (DataDictionary.Remove(key))
SaveToLocal();
}
}
#endregion
#region 其他
/// <summary>
/// 保存到本地
/// </summary>
private void SaveToLocal()
{
lock (locks)
{
try
{
string json = JsonConvert.SerializeObject(DataDictionary, Formatting.Indented);
File.WriteAllText(JsonPath, json);
}
catch (Exception ex)
{
Debug.Log($"[LocalStorage]数据保存失败:{ex.Message}");
}
}
}
/// <summary>
/// 判断文件是否存在,不存在则创建
/// </summary>
private bool EnsureFileExists()
{
try
{
if (!File.Exists(JsonPath))
{
Directory.CreateDirectory(Path.GetDirectoryName(JsonPath));
File.WriteAllText(JsonPath, "{}"); // 初始化空JSON对象
return true;
}
return false;
}
catch (Exception ex)
{
Debug.Log($"[LocalStorage]文件创建失败:{ex.Message}");
return false;
}
}
#endregion
}
/// <summary>
/// 约束 T 只能是自定义的类,防止写入时滥用其他系统类
/// </summary>
public interface IAllowedType { }
三、接口的调用
当前接口的示例使用的上面的旧版 LocalStorage.cs 来进行展示的,在源码可能有部分改动,大部分应该都对的上,个人推荐使用简单版的。
1.添加键值对
SetValue 这个方法我添加了泛型约束, T 只能是值类型,所以下面我又添加了一个 string 类型的重载方法,这里主要的目的是,既然是简单的存储系统,就尽量不要存储那些比较复杂的数据结构。
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.SetValue("myName", "张三");
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行后,自动生成了文件,并写入了 json

2.读取键值对
读取键值对,这里有几个重载方法
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
string name = localStorage.GetValue<string>("myName");
Console.WriteLine("name:{0}", name);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

也可以用反射指定 T 的类型
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
var name = localStorage.GetValue("myName", typeof(string));
Console.WriteLine("name:{0}", name);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
还可以使用 TryGetValue 方法,不必指定类,如果 out 变量的类型对应不上,则会报错。
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
string name;
bool isRes = localStorage.TryGetValue("myName", out name);
Console.WriteLine("isRes:{0},name:{1}", isRes, name);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

3.添加数组
SetList 方法这里依然是采用两个重载方法,用泛型约束限制了 T 的类型只能是值类型和 string 类型,一般来说,使用 List 用来存储数组类型已经完全够用了,原来还写了 SetArray 方法,后面删掉了。
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
List<string> list1 = new List<string>() { "a", "b", "c", "d" };
List<int> list2 = new List<int>() { 1, 34, 5, 23, 56, 64 };
localStorage.SetList("list1", list1);
localStorage.SetList("list2", list2);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

4.读取数组
读取数组也有几个重载,建议看下对应的接口
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
List<string> list1 = localStorage.GetList<string>("list1");
Console.WriteLine(string.Join(",", list1));
List<int> list2 = localStorage.GetList<int>("list2");
Console.WriteLine(string.Join(",", list2));
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

另一种读取方式,不需要指定接收值的类型
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
List<string> list;
bool isRes = localStorage.TryGetList("list1", out list);
Console.WriteLine("isRes:{0},list:{1}", isRes, string.Join(",", list));
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

5.数组追加数据
在 SetList 方法中,数组只能替换,不能向数组追加数据,所以后面我又添加了一个方法 ListAdd,用来向指定 key 内的数组添加数据,如果当前的 key 不存在,那么就自动创建一个键值对,value类型为数组。
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.ListAdd("list2", 3);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

如果 key 不存在,会自动创建一个新的键值对,比如:
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.ListAdd("age", 4);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

6.删除指定的key
会删除整个键值对
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.Remove("age");
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

7.删除指定key中指定的元素
这里有两个重载,可以根据对应的需求来使用
1.删除指定 key 指定起点开始指定个数的数组
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.Remove("list1", 1, 3);
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

2.删除指定 key 中对应的元素
代码:
namespace LocalSave
{
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\Config\\LocalStorage.json";
LocalStorage localStorage = new LocalStorage(path);
localStorage.Remove("list2", new List<int> { 1, 34, 5, 23, 56 });
Console.WriteLine("\n执行完成");
Console.ReadKey();
}
}
}
运行:

源码下载地址:
https://download.youkuaiyun.com/download/qq_38693757/90408820
源码和上面的代码稍微有一些不同
结束
如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢
end
824

被折叠的 条评论
为什么被折叠?



