如何通过shareName获取Xamarin.Essentials.Preferences对应分组的所有配置
sharedName的核心作用
sharedName的设计初衷不是为了支持批量读取,而是实现配置的分组隔离能力,对应原生平台的底层存储标识:
- 避免同应用内的key冲突:不同业务模块、不同功能域的配置可以用不同的sharedName分组,就算两个模块使用了完全相同的key,也不会出现配置互相覆盖的问题
- 支持跨应用共享配置:Android平台对应SharedPreferences的存储名称,同签名的应用可以通过相同的sharedName共享配置;iOS平台对应NSUserDefaults的SuiteName,同一App Group下的应用/扩展可以通过sharedName共享配置
原生平台本身没有提供批量读取同sharedName下所有配置项的API,因此Xamarin.Essentials也没有封装对应的批量获取方法。
更优雅的实现方案
你提到的拼接分隔符的方案容易出现转义错误、类型丢失等问题,推荐以下两种更稳定的实现方式:
方案1:预定义key数组封装批量读取方法
如果需要保留单key独立存储的逻辑,可以提前把同一分组下的所有key维护为常量数组,封装统一的批量读取方法:
// 预定义当前分组的所有key和sharedName const string BreakfastSharedName = "BreakfastPrefs"; private static readonly string[] _breakfastPrefKeys = new[] { "EggSwitch", "BaconSwitch" }; // 批量读取方法 public static Dictionary<string, bool> GetAllBreakfastPrefs() { var prefsDict = new Dictionary<string, bool>(); foreach (var key in _breakfastPrefKeys) { prefsDict[key] = Preferences.Get(key, false, BreakfastSharedName); } return prefsDict; }
这种方式维护成本低,不需要修改现有存储逻辑,新增配置项只需要在key数组中添加对应的key即可。
方案2:序列化整个配置类存储
如果你的配置结构是固定的,更推荐直接将整个配置类序列化后作为单条记录存储,完全避免key维护成本:
// 定义配置实体类 public class BreakfastConfig { public bool Eggs { get; set; } public bool Bacon { get; set; } } const string BreakfastSharedName = "BreakfastPrefs"; const string BreakfastConfigKey = "BreakfastConfig"; // 存储逻辑 public void SaveBreakfastConfig(BreakfastConfig config) { var json = System.Text.Json.JsonSerializer.Serialize(config); Preferences.Set(BreakfastConfigKey, json, BreakfastSharedName); } // 读取逻辑 public BreakfastConfig GetBreakfastConfig() { var json = Preferences.Get(BreakfastConfigKey, string.Empty, BreakfastSharedName); if (string.IsNullOrEmpty(json)) return new BreakfastConfig(); return System.Text.Json.JsonSerializer.Deserialize<BreakfastConfig>(json); }
这种方式还能完全避免key拼写错误的问题,新增配置项只需要修改BreakfastConfig类的属性即可,不需要额外修改存储读取逻辑。
注意:你贴出的示例代码中存在key大小写不匹配的问题,读取用的是EggSwitch,存储用的是Eggswitch,偏好存储是区分大小写的,会导致存储的配置无法正常读取,需要修正。
内容的提问来源于stack exchange,提问作者MisterZeeba
相关产品推荐
相关产品推荐

