Xamarin.Essentials.Preferences泛型包装类报错及解决方案咨询
Xamarin.Essentials.Preferences 泛型包装类实现方案
你遇到的无法从'T'转换为'string'错误,本质是编译器无法为泛型T匹配到Preferences.Set的对应重载,只能默认尝试调用接收string参数的重载,导致类型转换失败。下面提供两种可行的实现方案:
方案一:利用dynamic自动匹配重载(推荐)
通过dynamic绕过编译时类型检查,让运行时根据实际值的类型匹配Preferences对应的Set/Get重载,代码简洁且兼容所有支持的类型:
public class PreferenceManager { private static PreferenceManager _instance; private static readonly object _lock = new object(); private PreferenceManager() { } public static PreferenceManager Instance { get { lock (_lock) { _instance ??= new PreferenceManager(); return _instance; } } } public void SetPreference<T>(string key, T value) { Preferences.Set(key, (dynamic)value); } public T GetPreference<T>(string key, T defaultValue = default) { try { return (T)(dynamic)Preferences.Get(key, defaultValue); } catch { return defaultValue; } } }
说明
dynamic会在运行时解析实际类型,自动匹配Preferences中对应的重载方法,无需手动枚举类型。- 添加默认值参数后,
GetPreference的使用体验和原生API一致,读取失败时返回默认值。
方案二:手动枚举支持的类型
如果希望编译时就确定调用的重载,可以手动判断类型并调用对应方法,适合需要严格类型检查的场景:
public class PreferenceManager { private static PreferenceManager _instance; private static readonly object _lock = new object(); private PreferenceManager() { } public static PreferenceManager Instance { get { lock (_lock) { _instance ??= new PreferenceManager(); return _instance; } } } public void SetPreference<T>(string key, T value) { switch (value) { case string str: Preferences.Set(key, str); break; case int intVal: Preferences.Set(key, intVal); break; case bool boolVal: Preferences.Set(key, boolVal); break; case double doubleVal: Preferences.Set(key, doubleVal); break; case float floatVal: Preferences.Set(key, floatVal); break; case long longVal: Preferences.Set(key, longVal); break; case DateTime dateVal: Preferences.Set(key, dateVal); break; default: throw new NotSupportedException($"类型 {typeof(T)} 不被Preferences支持"); } } public T GetPreference<T>(string key, T defaultValue = default) { var type = typeof(T); if (type == typeof(string)) return (T)(object)Preferences.Get(key, defaultValue as string); else if (type == typeof(int)) return (T)(object)Preferences.Get(key, defaultValue is int val ? val : default(int)); else if (type == typeof(bool)) return (T)(object)Preferences.Get(key, defaultValue is bool bVal ? bVal : default(bool)); else if (type == typeof(double)) return (T)(object)Preferences.Get(key, defaultValue is double dVal ? dVal : default(double)); // 按需补充其他Xamarin支持的类型 else throw new NotSupportedException($"类型 {type} 不被Preferences支持"); } }
注意事项
- 两种方案都需要确保
T是Xamarin.Essentials.Preferences支持的类型(如string、int、bool、DateTime等),否则会抛出异常。 - 对于可空值类型(如
int?),方案一的dynamic方式可自动处理,方案二需要额外添加对应的类型判断分支。
内容的提问来源于stack exchange,提问作者COMAVLER
相关产品推荐
相关产品推荐

