數據類型序列化-封裝

/// <summary>
/// 定義泛型接口
/// </summary>
/// <typeparam name="T">T</typeparam>
public interface ISettingValue<T>
{/// <summary>/// value/// </summary>T DoubleValue { get; }/// <summary>/// key/// </summary>string StringValue { get; }
}/// <summary>/// GenericSetting/// </summary>public abstract class GenericSetting : ISettingValue<double>{/// <summary>/// value[double]/// </summary>public abstract double DoubleValue { get; }/// <summary>/// value[string]/// </summary>public abstract string StringValue { get; }/// <summary>/// value[double[]]/// </summary>public abstract double[] DoubleValues { get; }/// <summary>/// value[double[][]]/// </summary>public abstract double[][] ArrayDoubleValues { get; }/// <summary>/// value[string[]]/// </summary>public abstract string[] StringValues { get; }/// <summary>/// 重寫ToString方法,返回GenericSetting拼接json/// </summary>/// <returns></returns>public new abstract string ToString();/// <summary>/// abstract FromString/// </summary>/// <param name="info">string</param>/// <returns></returns>public abstract bool FromString(string info);public static implicit operator string(GenericSetting gs){Setting setting = gs as Setting;if (setting == null){throw new Exception("Not a Setting!");}if (setting.Strings == null && setting.Strings.Length != 0){throw new Exception("Setting has no Strings.");}return setting.Strings[0];}public static implicit operator string[](GenericSetting gs){Setting setting = gs as Setting;if (setting == null){return null;}if (setting.Strings == null){throw new Exception("Setting has no Strings.");}return setting.Strings;}public static implicit operator double(GenericSetting gs){Setting setting = gs as Setting;if (setting == null){throw new Exception("Not a Setting!");}if (setting.Values == null && setting.Values.Length != 0){throw new Exception("Setting has no Values.");}return setting.Values[0];}public static implicit operator int(GenericSetting gs){Setting setting = gs as Setting;if (setting == null){throw new Exception("Not a Setting!");}if (setting.Values == null && setting.Values.Length != 0){throw new Exception("Setting has no Values.");}return (int)setting.Values[0];}public static implicit operator int[](GenericSetting gs){Setting setting = gs as Setting;if (setting == null){return null;}if (setting.Values == null){throw new Exception("Setting has no Values.");}double[] values = setting.Values;int[] array = new int[values.Length];for (int i = 0; i < array.Length; i++){array[i] = (int)values[i];}return array;}public static implicit operator double[](GenericSetting gs){Setting setting = gs as Setting;if (setting == null){return null;}if (setting.Values == null){throw new Exception("Setting has no Values.");}return setting.Values;}public static implicit operator double[][](GenericSetting gs){Setting setting = gs as Setting;if (setting == null){return null;}if (setting.Values == null){throw new Exception("Setting has no Values.");}return setting.ArrayValues;}public static implicit operator GenericSetting(double val){Setting setting = new Setting();setting.Values = new double[1] { val };setting.Strings = new string[0];return setting;}public static implicit operator GenericSetting(string val){Setting setting = new Setting();setting.Values = new double[0];setting.Strings = new string[1] { val };return setting;}public static implicit operator GenericSetting(string[] vals){Setting setting = new Setting();if (vals == null){return setting;}string[] array = new string[vals.Length];for (int i = 0; i < vals.Length; i++){array[i] = vals[i];}setting.Strings = array;setting.Values = new double[0];return setting;}public static implicit operator GenericSetting(double[] vals){Setting setting = new Setting();if (vals == null){return setting;}double[] array = new double[vals.Length];for (int i = 0; i < vals.Length; i++){array[i] = vals[i];}setting.Values = array;setting.Strings = new string[0];return setting;}public static implicit operator GenericSetting(double[][] arrayVals){Setting setting = new Setting();if (arrayVals == null){return setting;}setting.Values = new double[0];setting.Strings = new string[0];setting.ArrayValues = arrayVals;return setting;}/// <summary>/// Initializes a new instance of the <see cref="GenericSetting"/> class./// </summary>protected GenericSetting(){}}/// <summary>/// Setting/// </summary>[Serializable]public class Setting : GenericSetting, ISerializable{/// <summary>/// 附件信息/// </summary>protected Dictionary<string, string> otherInfo;/// <summary>/// double[]/// </summary>protected double[] iVal;/// <summary>/// double[][]/// </summary>protected double[][] iArrayVal;/// <summary>/// string[]/// </summary>protected string[] iStr;/// <summary>/// 時間戳/// </summary>public string TimeStamp => otherInfo["SettingTimeStamp"];/// <summary>/// 協議版本【暫未使用】/// </summary>public int Version => int.Parse(otherInfo["SettingVersion"]);/// <summary>/// Unit/// </summary>public string Units{get{if (otherInfo.ContainsKey("SettingUnits")){return otherInfo["SettingUnits"];}return "NotExist";}}/// <summary>/// 附加信息/// </summary>public Dictionary<string, string> OtherInfo{get{if (otherInfo == null){otherInfo = new Dictionary<string, string>();}return otherInfo;}set{otherInfo = value;}}/// <summary>/// double[]/// </summary>public double[] Values{get{return iVal;}set{iVal = value;OtherInfo["SettingTimeStamp"] = DateTime.Now.ToString("yyyy-M-d tt H:mm:ss.ffffff", CultureInfo.InvariantCulture);OtherInfo["SettingVersion"] = VersionInfo.GetVersion().ToString();}}/// <summary>/// double[][]/// </summary>public double[][] ArrayValues{get{return iArrayVal;}set{iArrayVal = value;OtherInfo["SettingTimeStamp"] = DateTime.Now.ToString("yyyy-M-d tt H:mm:ss.ffffff", CultureInfo.InvariantCulture);OtherInfo["SettingVersion"] = VersionInfo.GetVersion().ToString();}}/// <summary>/// string[]/// </summary>public string[] Strings{get{return iStr;}set{iStr = value;OtherInfo["SettingTimeStamp"] = DateTime.Now.ToString("yyyy-M-d tt H:mm:ss.ffffff", CultureInfo.InvariantCulture);OtherInfo["SettingVersion"] = VersionInfo.GetVersion().ToString();}}/// <summary>/// 獲取附件信息/// </summary>/// <param name="key">附加信息key</param>/// <returns></returns>public string this[string key]{get{return otherInfo[key];}set{otherInfo[key] = value;}}/// <summary>/// Initializes a new instance of the <see cref="Setting"/> class./// </summary>public Setting(){otherInfo = new Dictionary<string, string>();iVal = new double[0];iStr = new string[0];iArrayVal = new double[0][];}/// <summary>/// Initializes a new instance of the <see cref="Setting"/> class./// </summary>/// <param name="gs">GenericSetting</param>public Setting(GenericSetting gs){Setting setting = gs as Setting;if (setting == null){throw new Exception("Not a Setting!");}iVal = new double[setting.iVal.Length];setting.iVal.CopyTo(iVal, 0);iStr = new string[setting.iStr.Length];setting.iStr.CopyTo(iStr, 0);otherInfo = new Dictionary<string, string>();string[] array = setting.otherInfo.Keys.ToArray();foreach (string key in array){otherInfo[key] = setting.otherInfo[key];}}/// <summary>/// Initializes a new instance of the <see cref="Setting"/> class. /// </summary>/// <param name="old">Copy</param>public Setting(Setting old){iVal = new double[old.iVal.Length];old.iVal.CopyTo(iVal, 0);iStr = new string[old.iStr.Length];old.iStr.CopyTo(iStr, 0);otherInfo = new Dictionary<string, string>();string[] array = old.otherInfo.Keys.ToArray();foreach (string key in array){otherInfo[key] = old.otherInfo[key];}}public static implicit operator Setting(double val){Setting setting = new Setting();setting.Values = new double[1] { val };setting.Strings = new string[0];return setting;}public static implicit operator Setting(string val){Setting setting = new Setting();setting.Values = new double[0];setting.Strings = new string[1] { val };return setting;}public static implicit operator Setting(string[] vals){Setting setting = new Setting();string[] array = new string[vals.Length];for (int i = 0; i < vals.Length; i++){array[i] = vals[i];}setting.Strings = array;setting.Values = new double[0];return setting;}public static implicit operator Setting(double[] vals){Setting setting = new Setting();double[] array = new double[vals.Length];for (int i = 0; i < vals.Length; i++){array[i] = vals[i];}setting.Values = array;setting.Strings = new string[0];return setting;}public static implicit operator Setting(double[][] vals){Setting setting = new Setting();setting.Values = new double[0];setting.Strings = new string[0];setting.ArrayValues = vals;return setting;}/// <summary>/// SettingTimeStamp to DateTime/// </summary>/// <returns></returns>public DateTime GetTimeStamp(){return DateTime.Parse(OtherInfo["SettingTimeStamp"], CultureInfo.InvariantCulture);}public string[] getOtherInfoKeys(){List<string> list = OtherInfo.Keys.ToList();list.Sort();return list.ToArray();}public string[] getOtherInfoStrings(){Dictionary<string, string> dictionary = OtherInfo;List<string> list = dictionary.Keys.ToList();list.Sort();string[] array = new string[list.Count];for (int i = 0; i < array.Length; i++){array[i] = dictionary[list[i]];}return array;}/// <summary>/// override ToString/// </summary>/// <returns></returns>public override string ToString(){return ToString();}/// <summary>/// ToString with level/// </summary>/// <param name="level">string</param>/// <returns></returns>public string ToString(string level = ""){string text = "{\n" + level + "\t\"OtherInfo\": {\n";bool flag = true;List<string> list = otherInfo.Keys.ToList();list.Sort();foreach (string item in list){if (flag){flag = false;}else{text += ",\n";}text = text + level + "\t\t\"" + item + "\":\"" + otherInfo[item] + "\"";}text = text + "\n" + level + "\t},\n";text = text + level + "\t\"Values\": [";string text2 = "";for (int i = 0; i < iVal.Length; i++){text = (!double.IsPositiveInfinity(iVal[i])) ? ((!double.IsNegativeInfinity(iVal[i])) ? ((!double.IsNaN(iVal[i])) ? (text + text2 + iVal[i]) : (text + text2 + "NaN")) : (text + text2 + "-Infinity")) : (text + text2 + "Infinity");text2 = ",";}text += "],\n";text = text + level + "\t\"Strings\": [";text2 = "";for (int j = 0; j < iStr.Length; j++){text = text + text2 + "\"" + iStr[j].Replace("\\", "\\\\") + "\"";text2 = ",";}return text + "]\n" + level + "}";}/// <summary>/// FromString/// </summary>/// <param name="info">string</param>/// <returns></returns>public override bool FromString(string info){try{string text = "\"OtherInfo\": {";int num = info.IndexOf(text) + text.Length;int num2 = info.IndexOf("}", num);string text2 = info.Substring(num, num2 - num);List<string> list = new List<string>();while (text2.Contains("\"")){int num3 = text2.IndexOf("\"");int num4 = text2.IndexOf("\"", num3 + 1);list.Add(text2.Substring(num3 + 1, num4 - num3 - 1));text2 = text2.Substring(num4 + 1);}for (int i = 0; i < list.Count; i += 2){otherInfo[list[i]] = list[i + 1];}text = "\"Values\": [";int num5 = info.IndexOf(text) + text.Length;int num6 = info.IndexOf("]", num5);string text3 = info.Substring(num5, num6 - num5);List<string> list2 = new List<string>();while (text3.Contains(",")){int num7 = text3.IndexOf(",");if (num7 == -1){break;}list2.Add(text3.Substring(0, num7));text3 = text3.Substring(num7 + 1);}if (text3 != ""){list2.Add(text3);}iVal = new double[list2.Count];for (int j = 0; j < list2.Count; j++){if (!double.TryParse(list2[j], out iVal[j])){if (list2[j] == "Infinity"){iVal[j] = double.PositiveInfinity;}else if (list2[j] == "-Infinity"){iVal[j] = double.NegativeInfinity;}else{iVal[j] = double.NaN;}}}text = "\"Strings\": [";num5 = info.IndexOf(text) + text.Length;num6 = info.IndexOf("]", num5);text3 = info.Substring(num5, num6 - num5);list2 = new List<string>();while (text3.Contains(",")){int num8 = text3.IndexOf(",");if (num8 == -1){break;}list2.Add(text3.Substring(0, num8));text3 = text3.Substring(num8 + 1);}if (text3 != ""){list2.Add(text3);}iStr = new string[list2.Count];for (int k = 0; k < list2.Count; k++){iStr[k] = list2[k].Substring(1, list2[k].Length - 2).Replace("\\\\", "\\");if (iStr[k].Contains("\"")){iStr[k] = iStr[k].Substring(iStr[k].IndexOf("\"") + 1);if (iStr[k].Contains("\"")){iStr[k] = iStr[k].Substring(0, iStr[k].LastIndexOf("\""));}}}}catch{return false;}return true;}/// <summary>/// Initializes a new instance of the <see cref="Setting"/> class.  反序列化構造方法[實現反序列化]/// </summary>/// <param name="info">SerializationInfo</param>/// <param name="context">StreamingContext</param>protected Setting(SerializationInfo info, StreamingContext context){otherInfo = new Dictionary<string, string>();string[] array = info.GetValue("otherInfoKeys", typeof(string[])) as string[];string[] array2 = info.GetValue("otherInfoValues", typeof(string[])) as string[];for (int i = 0; i < array.Length; i++){otherInfo[array[i]] = array2[i];}iVal = info.GetValue("iVal", typeof(double[])) as double[];iStr = info.GetValue("iStr", typeof(string[])) as string[];iArrayVal = info.GetValue("iArrayVal", typeof(double[][])) as double[][];}/// <summary>/// 序列化方法/// </summary>/// <param name="info">SerializationInfo</param>/// <param name="context">StreamingContext</param>public virtual void GetObjectData(SerializationInfo info, StreamingContext context){info.AddValue("iStr", iStr);info.AddValue("iVal", iVal);info.AddValue("iArrayVal", iArrayVal);info.AddValue("otherInfoKeys", otherInfo.Keys.ToArray());info.AddValue("otherInfoValues", otherInfo.Values.ToArray());}/// <summary>/// double/// </summary>public override double DoubleValue => Values?.Length > 0 ? Values[0] : default;/// <summary>/// string/// </summary>public override string StringValue => Strings?.Length > 0 ? Strings[0] : default;/// <summary>/// double[]/// </summary>public override double[] DoubleValues => Values;/// <summary>/// string[]/// </summary>public override string[] StringValues => Strings;/// <summary>/// double[][]/// </summary>public override double[][] ArrayDoubleValues => ArrayValues;}[Serializable]public class SettingContainer : Setting, ISerializable{public Dictionary<string, SettingContainer> SettingsContainers;public Dictionary<string, Setting> Settings;private static string delimiter;private static List<string> m_OtherInfoKeys;[NonSerialized]private string[] skeys;[NonSerialized]private Setting[] sValues;[NonSerialized]private string[] sckeys;[NonSerialized]private SettingContainer[] scValues;[NonSerialized]private bool isDeserialized;/// <summary>/// split "."/// </summary>public static string Delimiter => delimiter;/// <summary>/// get/set value with key/// </summary>/// <param name="key">string</param>/// <returns></returns>public GenericSetting this[string key]{get{int num = key.IndexOf(delimiter);if (num > 0){string text = key.Substring(0, num);string text2 = key.Substring(num + 1);SettingContainer settingContainer = null;if (SettingsContainers != null && SettingsContainers.ContainsKey(text)){settingContainer = SettingsContainers[text];try{return settingContainer[text2];}catch (Exception innerException){throw new Exception("Can not find key " + key + " (failed in" + text2 + ")", innerException);}}throw new Exception("Can not find key " + key + " (missing " + text + ")");}if (Settings != null && Settings.ContainsKey(key)){return Settings[key];}if (SettingsContainers == null || !SettingsContainers.ContainsKey(key)){throw new Exception("Can't find key " + key);}return SettingsContainers[key];}set{int num = key.IndexOf(delimiter);if (num > 0){string key2 = key.Substring(0, num);string key3 = key.Substring(num + 1);if (SettingsContainers == null){SettingsContainers = new Dictionary<string, SettingContainer>();}if (!SettingsContainers.ContainsKey(key2)){SettingsContainers[key2] = new SettingContainer();}SettingsContainers[key2][key3] = value;}else if (value is Setting){if (Settings == null){Settings = new Dictionary<string, Setting>();}Settings[key] = value as Setting;}else if (value is SettingContainer){if (SettingsContainers == null){SettingsContainers = new Dictionary<string, SettingContainer>();}SettingsContainers[key] = value as SettingContainer;}else{if (value != null){throw new Exception("value can not be set into " + key);}if (Settings != null && Settings.ContainsKey(key)){Settings.Remove(key);}if (SettingsContainers != null && SettingsContainers.ContainsKey(key)){SettingsContainers.Remove(key);}}}}/// <summary>/// Initializes a new instance of the <see cref="SettingContainer"/> class. /// </summary>public SettingContainer(){}/// <summary>/// Initializes a new instance of the <see cref="SettingContainer"/> class./// </summary>/// <param name="old">SettingContainer</param>public SettingContainer(SettingContainer old){if (old.SettingsContainers != null){SettingsContainers = new Dictionary<string, SettingContainer>();string[] array = old.SettingsContainers.Keys.ToArray();foreach (string key in array){SettingsContainers[key] = new SettingContainer(old.SettingsContainers[key]);}}if (old.Settings != null){Settings = new Dictionary<string, Setting>();string[] array = old.Settings.Keys.ToArray();foreach (string key2 in array){Settings[key2] = new Setting(old.Settings[key2]);}}}public static implicit operator SettingContainer(Dictionary<string, double[]> dictionarySettings){SettingContainer settingContainer = new SettingContainer();settingContainer.updateSettings(dictionarySettings);return settingContainer;}public static implicit operator SettingContainer(Dictionary<string, string[]> dictionarySettings){SettingContainer settingContainer = new SettingContainer();settingContainer.updateStringSettings(dictionarySettings);return settingContainer;}public static implicit operator Dictionary<string, double[]>(SettingContainer gs){return gs.GetDictionary();}public static implicit operator Dictionary<string, string[]>(SettingContainer gs){return gs.GetStringDictionary();}/// <summary>/// ContainsKey/// </summary>/// <param name="key">string</param>/// <returns>bool</returns>public bool ContainsKey(string key){return Keys().Contains(key);}/// <summary>/// get keys/// </summary>/// <param name="superKey">superKey</param>/// <returns>List<string></returns>public List<string> Keys(string superKey = ""){List<string> list = new List<string>();if (SettingsContainers != null){foreach (string key in SettingsContainers.Keys){foreach (string item in SettingsContainers[key].Keys(superKey + key + ".")){list.Add(item);}}}if (Settings != null){foreach (string key2 in Settings.Keys){list.Add(superKey + key2);}return list;}return list;}public GenericSetting NullableGet(string key){int num = key.IndexOf(delimiter);if (num > 0){string key2 = key.Substring(0, num);string key3 = key.Substring(num + 1);if (SettingsContainers != null && SettingsContainers.ContainsKey(key2)){return SettingsContainers[key2]?.NullableGet(key3);}return null;}if (Settings != null && Settings.ContainsKey(key)){return Settings[key];}if (SettingsContainers != null){if (SettingsContainers.ContainsKey(key)){return SettingsContainers[key];}return null;}return null;}public Dictionary<string, Setting> GetSettingDictionary(){Dictionary<string, Setting> dictionary = new Dictionary<string, Setting>();if (Settings != null){foreach (string key in Settings.Keys){dictionary[key] = Settings[key];}}Dictionary<string, SettingContainer> dictionary2 = null;bool flag;if (flag = SettingsContainers != null){dictionary2 = SettingsContainers;}while (flag){Dictionary<string, SettingContainer> dictionary3 = new Dictionary<string, SettingContainer>();new List<SettingContainer>();foreach (string key2 in dictionary2.Keys){SettingContainer settingContainer = dictionary2[key2];if (settingContainer.SettingsContainers != null){foreach (string key3 in settingContainer.SettingsContainers.Keys){dictionary3[key2 + delimiter + key3] = settingContainer.SettingsContainers[key3];}}if (settingContainer.Settings == null){continue;}foreach (string item in settingContainer.Settings.Keys.ToList()){dictionary[key2 + delimiter + item] = settingContainer.Settings[item];}}dictionary2 = dictionary3;flag = dictionary2.Count > 0;}return dictionary;}public Dictionary<string, double[]> GetDictionary(){Dictionary<string, double[]> dictionary = new Dictionary<string, double[]>();Dictionary<string, Setting> settingDictionary = GetSettingDictionary();foreach (string key in settingDictionary.Keys){if (settingDictionary[key].Values.Length != 0){dictionary[key] = new double[settingDictionary[key].Values.Length];settingDictionary[key].Values.CopyTo(dictionary[key], 0);}}return dictionary;}public Dictionary<string, string[]> GetStringDictionary(bool withOtherInfo = true){Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();Dictionary<string, Setting> settingDictionary = GetSettingDictionary();foreach (string key in settingDictionary.Keys){if (withOtherInfo){foreach (string key2 in settingDictionary[key].OtherInfo.Keys){dictionary[key + delimiter + key2] = new string[1] { settingDictionary[key].OtherInfo[key2] };}}if (settingDictionary[key].Strings.Length != 0){dictionary[key] = new string[settingDictionary[key].Strings.Length];settingDictionary[key].Strings.CopyTo(dictionary[key], 0);}}return dictionary;}public void updateSettings(Dictionary<string, double[]> DictionarySettings){Dictionary<string, Setting> settingDictionary = GetSettingDictionary();foreach (string key in DictionarySettings.Keys){try{Setting setting = null;setting = (Setting)(settingDictionary.ContainsKey(key) ? settingDictionary[key] : (this[key] = new Setting()));setting.Values = DictionarySettings[key].ToArray();}catch (Exception innerException){throw new Exception("Error with key " + key, innerException);}}}public void updateStringSettings(Dictionary<string, string[]> DictionarySettings){Dictionary<string, Setting> settingDictionary = GetSettingDictionary();foreach (string key in DictionarySettings.Keys){string text = null;string text2 = null;try{int num = key.LastIndexOf(delimiter);if (num > 0){text = key.Substring(num + 1);}if (m_OtherInfoKeys.Contains(text)){text2 = key.Substring(0, num);}else{text = null;text2 = key;}Setting setting = null;setting = (Setting)(settingDictionary.ContainsKey(text2) ? settingDictionary[text2] : (this[text2] = (settingDictionary[text2] = new Setting())));if (text == null){string[] source = DictionarySettings[text2];setting.Strings = source.ToArray();}else if (DictionarySettings[key].Length != 0){setting.OtherInfo[text] = DictionarySettings[key][0];}}catch{throw;}}}/// <summary>/// Initializes a new instance of the <see cref="SettingContainer"/> class.  反序列化構造方法[實現反序列化]/// </summary>/// <param name="info">SerializationInfo</param>/// <param name="context">StreamingContext</param>protected SettingContainer(SerializationInfo info, StreamingContext context){skeys = info.GetValue("DictionarySettingsKeys", typeof(string[])) as string[];sValues = info.GetValue("DictionarySettingsValues", typeof(Setting[])) as Setting[];sckeys = info.GetValue("DictionarySettingContainersKeys", typeof(string[])) as string[];scValues = info.GetValue("DictionarySettingContainersValues", typeof(SettingContainer[])) as SettingContainer[];}/// <summary>/// 序列化方法/// </summary>/// <param name="info">SerializationInfo</param>/// <param name="context">StreamingContext</param>public virtual void GetObjectData(SerializationInfo info, StreamingContext context){if (Settings != null){info.AddValue("DictionarySettingsKeys", Settings.Keys.ToArray());info.AddValue("DictionarySettingsValues", Settings.Values.ToArray());}else{info.AddValue("DictionarySettingsKeys", null);info.AddValue("DictionarySettingsValues", null);}if (SettingsContainers != null){info.AddValue("DictionarySettingContainersKeys", SettingsContainers.Keys.ToArray());info.AddValue("DictionarySettingContainersValues", SettingsContainers.Values.ToArray());}else{info.AddValue("DictionarySettingContainersKeys", null);info.AddValue("DictionarySettingContainersValues", null);}}[OnDeserialized]internal void OnDeserialized(StreamingContext context){if (skeys != null){Settings = new Dictionary<string, Setting>();for (int i = 0; i < skeys.Length; i++){Settings[skeys[i]] = sValues[i];}skeys = null;sValues = null;}if (sckeys != null){SettingsContainers = new Dictionary<string, SettingContainer>();for (int j = 0; j < sckeys.Length; j++){SettingsContainers[sckeys[j]] = scValues[j];}sckeys = null;scValues = null;}isDeserialized = true;}public override string ToString(){return ToString("");}public string ToString(string level){string text = "{\n";bool flag = true;if (SettingsContainers != null){text = text + level + "\t\"SettingsContainers\": {\n";List<string> list = SettingsContainers.Keys.ToList();list.Sort();foreach (string item in list){if (flag){flag = false;}else{text += ",\n";}text = text + level + "\t\t\"" + item + "\": ";text += SettingsContainers[item].ToString(level + "\t\t");}text = text + "\n\t" + level + "},\n";}else{text = text + level + "\t\"SettingsContainers\": null,\n";}flag = true;if (Settings != null){text = text + level + "\t\"Settings\": {\n";List<string> list2 = Settings.Keys.ToList();list2.Sort();foreach (string item2 in list2){if (flag){flag = false;}else{text += ",\n";}text = text + level + "\t\t\"" + item2 + "\": ";text += Settings[item2].ToString(level + "\t\t");}text = text + "\n" + level + "\t}\n";}else{text = text + level + "\t\"Settings\": null\n";}return text + level + "}";}public override bool FromString(string info){return FromString2(info, "");}private bool FromString2(string info, string settingOrContainer){try{if (settingOrContainer == "settings"){SettingsContainers = null;Settings = new Dictionary<string, Setting>();}if (settingOrContainer == "SettingsContainers"){SettingsContainers = new Dictionary<string, SettingContainer>();Settings = null;}int num = 0;while (num > -1 && num < info.Length){int num2 = info.IndexOf("\"", num);if (num2 < 0){break;}int num3 = info.IndexOf("\"", num2 + 1);string text = info.Substring(num2 + 1, num3 - num2 - 1);int num4 = info.IndexOf("{", num3 + 1);int num5 = num4;int num6 = 1;int num7 = 0;int num8 = info.IndexOf(",", num3 + 1);if (num8 < num4){num = num8;continue;}if (num4 < 0){break;}while (num7 < num6){int num9 = info.IndexOf("{", num5 + 1);int num10 = info.IndexOf("}", num5 + 1);if (num9 < 0){num9 = info.Length;}if (num10 < 0){break;}if (num9 < num10){num6++;num5 = num9;}else{num7++;num5 = num10;}}string info2 = info.Substring(num4, num5 - num4 + 1);if (text == "Settings"){settingOrContainer = "settings";SettingContainer settingContainer = new SettingContainer();try{settingContainer.FromString2(info2, settingOrContainer);}catch{settingContainer = null;}Settings = settingContainer.Settings;}else if (settingOrContainer == "settings"){Setting setting = new Setting();try{setting.FromString(info2);}catch{setting = null;}Settings[text] = setting;}else if (text == "SettingsContainers"){settingOrContainer = "SettingsContainers";SettingContainer settingContainer2 = new SettingContainer();try{settingContainer2.FromString2(info2, settingOrContainer);}catch{settingContainer2 = null;}SettingsContainers = settingContainer2.SettingsContainers;}else if (settingOrContainer == "SettingsContainers"){SettingContainer settingContainer3 = new SettingContainer();try{settingContainer3.FromString(info2);}catch{settingContainer3 = null;}SettingsContainers[text] = settingContainer3;}num = num5 + 1;}}catch{return false;}return true;}public Dictionary<string, string> compare(SettingContainer other, bool swap = true, double tolerance = 0.0){Dictionary<string, string> dictionary = (!swap) ? new Dictionary<string, string>() : other.compare(this, swap: false);Dictionary<string, double[]> dictionary2 = GetDictionary();Dictionary<string, string[]> stringDictionary = GetStringDictionary();Dictionary<string, double[]> dictionary3 = other.GetDictionary();Dictionary<string, string[]> stringDictionary2 = other.GetStringDictionary();foreach (string key in dictionary2.Keys){double[] array = dictionary2[key];if (!dictionary3.ContainsKey(key)){dictionary[key] = "missing key";continue;}double[] array2 = dictionary3[key];if (array.Length != array2.Length){dictionary[key] = "mismatched size";continue;}for (int i = 0; i < array.Length; i++){if (double.IsNaN(array[i]) != double.IsNaN(array2[i]) && Math.Abs(array[i] - array2[i]) <= tolerance){dictionary[key + ";" + i] = "mismatched value " + array[i] + " != " + array2[i];}}}foreach (string key2 in stringDictionary.Keys){if (key2.Contains("SettingTimeStamp") || key2.Contains("AcuShape.PROCESSING.version")){continue;}if (!stringDictionary2.ContainsKey(key2)){dictionary[key2] = "missing key";continue;}if (stringDictionary[key2].Length != stringDictionary2[key2].Length){dictionary[key2] = "mismatched size";continue;}for (int j = 0; j < stringDictionary[key2].Length; j++){if (stringDictionary[key2][j] != stringDictionary2[key2][j]){dictionary[key2 + ";" + j] = "mismatched value";}}}return dictionary;}static SettingContainer(){delimiter = ".";m_OtherInfoKeys = new List<string> { "SettingTimeStamp", "SettingUnits", "SettingVersion" };}}public class VersionInfo{public const string Version = "1.0.0.0";public static string GetVersion(){return Version;}public VersionInfo(){}}

配置數據管理體系:ISettingValue<T>GenericSettingSetting?與?SettingContainer?解析

一、體系整體定位與核心功能

該代碼片段構建了一套標準化的配置數據管理體系,核心用于工業控制、設備參數配置或系統設置等場景中,實現 “多類型數據統一存儲、序列化 / 反序列化、靈活訪問” 的需求。整個體系通過 “接口 - 抽象類 - 具體類 - 容器類” 的層級設計,覆蓋了從單一配置項到復雜嵌套配置的全場景,支持?doublestring?及多維數組類型,并提供 JSON 格式轉換、序列化、數據對比等核心能力。

二、核心組件與層級關系

整個體系的層級結構清晰,各組件職責單一且協同配合,具體關系如下:

ISettingValue 泛型接口

GenericSetting 抽象類

Setting 具體配置類

SettingContainer 配置容器類

嵌套存儲 Setting/SettingContainer

各組件的核心定位:

  • ISettingValue<T>:定義配置項的基礎訪問接口,約束 “值(DoubleValue)” 和 “鍵(StringValue)” 的獲取方式。
  • GenericSetting:抽象基類,擴展接口能力,支持多維數據(double[]/double[][]/string[]),并提供隱式類型轉換(如?GenericSetting?與?double/string/ 數組的互轉)。
  • Setting:具體配置實現類,支持序列化(ISerializable)、JSON 格式轉換(ToString/FromString),并存儲配置的附加信息(時間戳、版本、單位等)。
  • SettingContainer:配置容器類,基于字典結構存儲多個?Setting?或嵌套?SettingContainer,支持 “鍵路徑訪問”(如?container["parent.child.key"]),解決復雜嵌套配置的管理問題。

三、核心組件詳解

1. 泛型接口:ISettingValue<T>

核心作用

定義配置項的最小功能契約,約束所有配置類必須實現 “值” 和 “鍵” 的獲取邏輯,其中?T?默認為?double(由?GenericSetting?實現時指定)。

關鍵成員
成員類型作用說明
DoubleValueTdouble獲取配置的數值型值(核心數據)
StringValuestring獲取配置的字符串型鍵 / 描述(標識)
設計意義

通過接口標準化配置項的訪問方式,確保不同配置類的一致性,便于后續擴展和統一管理。

2. 抽象基類:GenericSetting

核心作用

作為?ISettingValue<double>?的實現者和?Setting?的基類,擴展多維數據支持和類型轉換能力,是整個體系的 “功能中轉站”。

關鍵成員與能力
(1)多維數據訪問(抽象屬性)

定義了覆蓋單值、一維數組、二維數組的抽象屬性,強制子類(Setting)實現數據存儲邏輯:

  • DoubleValue:單值?double(實現接口)
  • StringValue:單值?string(實現接口)
  • DoubleValuesdouble[](一維數值數組)
  • ArrayDoubleValuesdouble[][](二維數值數組)
  • StringValuesstring[](一維字符串數組)
(2)隱式類型轉換(核心亮點)

提供?11 種隱式轉換,支持?GenericSetting?與常見類型的無縫互轉,極大簡化代碼編寫。例如:

  • GenericSetting → double:直接獲取配置的第一個數值(Values[0]
  • double → GenericSetting:將單值?double?封裝為?Setting?對象
  • string[] → GenericSetting:將字符串數組封裝為?Setting?對象
  • GenericSetting → double[][]:直接獲取二維數值數組(ArrayValues

轉換示例代碼

csharp

// double 隱式轉為 GenericSetting
GenericSetting gs1 = 123.45; 
Console.WriteLine(gs1.DoubleValue); // 輸出 123.45// string[] 隱式轉為 GenericSetting
GenericSetting gs2 = new string[] { "name", "age" };
Console.WriteLine(gs2.StringValues[1]); // 輸出 "age"// GenericSetting 隱式轉為 double[]
double[] values = gs1; 
Console.WriteLine(values[0]); // 輸出 123.45
(3)序列化基礎方法

定義抽象方法?ToString()(JSON 序列化)和?FromString(string info)(JSON 反序列化),強制子類實現數據與字符串的轉換邏輯。

3. 具體配置類:Setting

核心作用

GenericSetting?的具體實現,是 “單一配置項” 的最終載體,支持序列化、附加信息存儲、JSON 解析,是體系中最常用的基礎配置單元。

關鍵成員與能力
(1)核心數據存儲字段
字段類型作用說明
iValdouble[]存儲數值型數據(對應?DoubleValues
iArrayValdouble[][]存儲二維數值型數據(對應?ArrayDoubleValues
iStrstring[]存儲字符串型數據(對應?StringValues
otherInfoDictionary<string, string>存儲附加信息(時間戳、版本、單位等)
(2)附加信息管理(實用功能)

通過?otherInfo?字典存儲配置的元數據,提供便捷訪問屬性:

  • TimeStamp:配置更新時間戳(格式:yyyy-M-d tt H:mm:ss.ffffff
  • Version:配置版本(來自?VersionInfo,默認?1.0.0.0
  • Units:數據單位(如 “℃”“m/s”,默認 “NotExist”)
  • 索引器?this[string key]:直接訪問附加信息(如?setting["SettingUnits"]
(3)JSON 序列化 / 反序列化(核心功能)
  • ToString(string level = ""):將配置數據(含附加信息、數值、字符串)轉換為格式化 JSON 字符串,支持縮進(level?參數控制縮進層級),便于人類閱讀和日志記錄。
    • 示例輸出:

      json

      {"OtherInfo": {"SettingTimeStamp":"2024-5-20 PM 3:30:45.123456","SettingVersion":"1.0.0.0","SettingUnits":"℃"},"Values": [25.5, 26.1],"Strings": ["Temperature1", "Temperature2"]
      }
      
  • FromString(string info):從 JSON 字符串解析配置數據,自動填充?iValiStrotherInfo,支持異常處理(解析失敗返回?false)。
(4)序列化支持(ISerializable

實現 .NET 序列化接口,支持跨進程 / 跨平臺數據傳輸,通過?GetObjectData?方法將核心字段(iValiStriArrayValotherInfo)寫入序列化流,反序列化時通過構造函數恢復數據。

4. 配置容器類:SettingContainer

核心作用

管理多個?Setting?或嵌套?SettingContainer,解決 “復雜配置場景”(如層級化系統設置、多設備參數集合)的存儲和訪問問題,相當于 “配置的字典容器”。

關鍵成員與能力
(1)核心存儲結構
字段類型作用說明
SettingsDictionary<string, Setting>存儲單一配置項(鍵 -Setting?映射)
SettingsContainersDictionary<string, SettingContainer>存儲嵌套容器(鍵 -SettingContainer?映射)
delimiterstring(靜態)鍵路徑分隔符(默認 “.”),用于層級訪問
(2)層級化鍵訪問(核心亮點)

通過?索引器?this[string key]?支持 “點分隔符” 的層級化訪問,無需手動逐層獲取嵌套容器,極大簡化代碼。例如:

  • 訪問嵌套配置:container["Device1.Temperature.SetPoint"],自動解析為?container → SettingsContainers["Device1"] → SettingsContainers["Temperature"] → Settings["SetPoint"]
  • 賦值嵌套配置:container["Device1.Temperature.SetPoint"] = 25.0,自動創建不存在的中間容器。

示例代碼

csharp

// 創建容器并添加嵌套配置
SettingContainer container = new SettingContainer();
// 直接賦值層級化配置(自動創建中間容器 Device1 和 Temperature)
container["Device1.Temperature.SetPoint"] = 25.0; 
container["Device1.Temperature.Unit"] = "℃";// 直接訪問層級化配置
double setPoint = (double)container["Device1.Temperature.SetPoint"];
string unit = (string)container["Device1.Temperature.Unit"];
Console.WriteLine($"SetPoint: {setPoint} {unit}"); // 輸出 "SetPoint: 25 ℃"
(3)配置集合操作

提供豐富的集合級操作方法,滿足批量管理需求:

  • Keys(string superKey = ""):獲取所有配置的鍵(含層級路徑,如?Device1.Temperature.SetPoint)。
  • GetSettingDictionary():將所有嵌套配置扁平化為 “鍵路徑 -Setting” 的字典,便于批量遍歷。
  • GetDictionary():將所有數值型配置扁平化為 “鍵路徑 -double[]” 的字典。
  • updateSettings(Dictionary<string, double[]> dict):批量更新數值型配置。
(4)配置對比(實用功能)

compare(SettingContainer other, bool swap = true, double tolerance = 0.0)?方法:

  • 對比當前容器與另一個容器的配置差異,返回差異字典(鍵路徑 - 差異描述)。
  • 支持數值容忍度(tolerance),避免浮點精度問題導致的誤判。
  • 支持忽略時間戳(SettingTimeStamp)和版本號(AcuShape.PROCESSING.version)等動態字段。
(5)JSON 序列化與反序列化

重寫?ToString(string level)?方法,將嵌套容器結構轉換為層級化 JSON(含?SettingsContainers?和?Settings?節點),反序列化時通過?FromString2?方法遞歸解析嵌套結構。

四、核心設計亮點

1. 類型安全與靈活性平衡

  • 通過隱式類型轉換簡化代碼(如?double?直接轉為?Setting),同時通過抽象類和接口約束確保類型安全。
  • 支持?double/string/ 多維數組等多種數據類型,覆蓋絕大多數配置場景。

2. 層級化配置管理

  • SettingContainer?的 “點分隔符” 索引器,解決嵌套配置的訪問痛點,比傳統字典嵌套更直觀。

3. 序列化與可移植性

  • 同時支持 JSON 字符串轉換(便于日志和人工編輯)和 .NET 序列化(便于跨進程傳輸),滿足不同場景的可移植需求。

4. 元數據管理

  • otherInfo?字典存儲時間戳、版本、單位等元數據,讓配置不僅包含 “數據”,還包含 “數據的描述信息”,便于追溯和維護。

五、典型應用場景

  1. 工業設備參數配置:存儲 PLC、傳感器的參數(如溫度閾值、電機轉速),通過?Setting?存儲單設備參數,SettingContainer?管理多設備集合。
  2. 系統設置管理:存儲軟件的層級化設置(如?System.Network.IPSystem.Serial.BaudRate),通過?SettingContainer?實現路徑化訪問。
  3. 配置備份與恢復:通過?ToString()?將配置轉為 JSON 字符串備份,恢復時通過?FromString()?解析,支持人工編輯備份文件。
  4. 配置對比與同步:通過?SettingContainer.compare()?方法對比本地與遠程設備的配置差異,實現增量同步。

六、使用注意事項

  1. 隱式轉換的異常風險:隱式轉換時會檢查?Setting?實例和數據長度(如?GenericSetting → double?要求?Values?非空且長度≥1),需確保數據合法性,避免拋出?Exception
  2. JSON 格式兼容性FromString()?方法依賴固定的 JSON 結構(含?OtherInfoValuesStrings?節點),自定義 JSON 時需遵循格式要求。
  3. 嵌套深度限制SettingContainer?的嵌套深度無硬限制,但過深的嵌套會影響性能和可讀性,建議控制在 3-5 層以內。
  4. 線程安全:當前實現未包含線程安全控制,多線程并發訪問時需手動添加鎖(如?lock),避免字典操作沖突。

七、總結

該配置數據管理體系通過 “接口 - 抽象類 - 具體類 - 容器類” 的層級設計,實現了 “單一配置項→復雜嵌套配置” 的全場景覆蓋,兼具類型安全、靈活性、可移植性三大優勢。無論是工業設備參數管理,還是軟件系統設置,都能通過該體系實現標準化、可維護的配置管理,是一套設計精良的配置解決方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97586.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97586.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97586.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PitVis-2023挑戰賽:內鏡下垂體瘤手術視頻中的手術流程識別|文獻速遞-深度學習人工智能醫療圖像

Title題目PitVis-2023 challenge: Workflow recognition in videos of endoscopic pituitary surgeryPitVis-2023挑戰賽&#xff1a;內鏡下垂體瘤手術視頻中的手術流程識別01文獻速遞介紹內鏡視覺挑戰賽與PitVis-2023挑戰賽背景及核心內容 “內鏡視覺&#xff08;EndoVis&#…

2025年8月個人工作生活總結

本文為 2025年8月工作生活總結。研發編碼 無處不在的AI 現在很多地方都在推AI&#xff0c;廣西的人工智能走在前列&#xff0c;要賦能各行各業。至于我&#xff0c;主要就是在寫點代碼&#xff0c;寫點交差的文檔。其實現在我已經有點分析哪些代碼哪些文字是AI寫的了。我工作用…

Dubbo常見面試題

1、默認使用的是什么通信框架&#xff0c;還有別的選擇嗎? 默認也推薦使用netty框架&#xff0c;還有mina。 2、服務調用是阻塞的嗎&#xff1f; 默認是阻塞的&#xff0c;可以異步調用&#xff0c;沒有返回值的可以這么做。 3、一般使用什么注冊中心&#xff1f;還有別的…

簡單的加密算法

// 加密函數&#xff08;32位版本&#xff09; //這里的 data 是ID&#xff0c; dword encrypt(dword data, dword key, int shift) {data ^ key; // 第一步&#xff1a;異或混淆// 循環左移&#xff08;shift范圍1-31&#xff09;return (data << sh…

升級的MS9125S USB投屏控制芯片(VGAHD輸出)

MS9125S是一款USB單芯片投屏器&#xff0c;內部集成了USB 2.0控制器和數據收發模塊、視頻DAC、HD接口和音視頻處理模塊&#xff0c;支持壓縮視頻傳輸。MS9125S可以通過USB接口顯示或者擴展PC、智能手機、平板電腦的顯示信息到更大尺寸的顯示設備上&#xff0c;支持VGA和HD視頻接…

求歐拉回路:Hierholzer算法圖解模擬

代碼模板&#xff1a;List<Integer> resultList new ArrayList<>();List<Integer> hierholzer() {dfs(0);resultList.add(0);// 數組反轉Collections.reverse(resultList);return resultList; }void dfs(int start) {for(int end : G[start]) {if(!vis[star…

Kafka面試精講 Day 2:Topic、Partition與Replica機制

【Kafka面試精講 Day 2】Topic、Partition與Replica機制 在“Kafka面試精講”系列的第二天&#xff0c;我們將深入剖析Kafka最核心的三大數據組織機制&#xff1a;Topic&#xff08;主題&#xff09;、Partition&#xff08;分區&#xff09;與Replica&#xff08;副本&#x…

【備戰2025數模國賽】(三)數模常見賽題類型及解決辦法

在進行數學建模競賽時&#xff0c;很多同學面臨的第一個挑戰是如何對賽題進行歸類&#xff0c;并選擇合適的模型。本篇梳理了數學建模中最常見的幾類賽題&#xff0c;并針對每類題型提供了基本的解決思路&#xff0c;幫助大家快速選擇合適的解題方法&#xff0c;高效完成模型構…

LabVIEW測斜設備承壓試驗臺

為保障煤礦井下地質勘探鉆孔中測斜裝備的可靠運行&#xff0c;設計基于 LabVIEW的鉆孔測斜設備承壓性能試驗臺。該試驗臺以氣動增壓泵為壓力執行元件&#xff0c;結合虛擬儀器與 PLC 控制技術&#xff0c;可精準模擬井下壓力環境&#xff0c;完成水壓、疲勞等試驗&#xff0c;實…

四、練習1:Git基礎操作

練習1&#xff1a;Git基礎操作 練習目標 通過實際操作掌握Git的基本命令&#xff0c;包括初始化倉庫、添加文件、提交更改等。 練習步驟 步驟1&#xff1a;環境準備 確保已安裝Git配置用戶信息&#xff08;如果未配置&#xff09; # 檢查Git版本 git --version# 配置用戶信息 g…

RK3399內核驅動實戰:獲取設備號控制LED的四種方法(由淺入深、代碼注釋詳盡)

RK3399 內核驅動實戰&#xff1a;獲取設備號控制 LED 的四種方法&#xff08;由淺入深、代碼注釋詳盡&#xff09; 在 Linux 字符設備驅動開發中&#xff0c;設備號&#xff08;major minor&#xff09;是內核與用戶空間溝通的橋梁。文章圍繞設備號這一條線展開&#xff0c;從…

2025年AI智能體開源技術棧全面解析:從基礎框架到垂直應用

2025年&#xff0c;開源AI智能體技術正以前所未有的速度重塑人工智能領域&#xff0c;從單一任務處理到復雜多智能體協作&#xff0c;開源生態已成為技術創新的核心驅動力。一、開源AI智能體生態概述 1.1 技術演進與發展歷程 AI智能體技術經歷了從規則式智能體&#xff08;2015…

Empire: LupinOne靶場滲透

Empire: LupinOne 來自 <https://www.vulnhub.com/entry/empire-lupinone,750/#top> 1&#xff0c;將兩臺虛擬機網絡連接都改為NAT模式 2&#xff0c;攻擊機上做namp局域網掃描發現靶機 nmap -sn 192.168.23.0/24 那么攻擊機IP為192.168.23.128&#xff0c;靶場IP192.16…

飛騰2000+/64核 PCIE掃描異常問題排查

1、背景介紹近期項目中采用全國產飛騰計算模塊搭配一塊FPGA模塊&#xff08;FPGA為復旦微的VU9P&#xff09;&#xff0c;實現業務數據的收發。FPGA中采用了Xilinx的XDMA IP核&#xff0c;飛騰計算模塊中的FT2000/64核處理器通過PEU1的一路 PCIE3.0x8與VU9P相連接&#xff0c;發…

證明與激勵:Walrus 可編程數據如何通過激勵可用性證明獲得安全性

Walrus 的可用性證明&#xff08;Proof of Availability&#xff0c;PoA&#xff09; 是部署在 Sui 上的鏈上憑證&#xff0c;它為數據托管創建了一個可驗證的公開記錄&#xff0c;并作為存儲服務正式啟動的標志。PoA 中的“激勵”來自一個健全的經濟框架&#xff1a;存儲節點需…

云存儲(參考自騰訊云計算工程師認證)

目錄 存儲基礎知識&#xff1a; RAID&#xff1a; 云存儲概述&#xff1a; 云存儲產品&#xff1a; CBS&#xff1a; CFS文件存儲&#xff1a; COS對象存儲&#xff1a; 云存儲安全&#xff1a; 存儲基礎知識&#xff1a; 機械硬盤&#xff1a;HDD&#xff0c;即傳統硬…

面試tips--JVM(2)--對象創建的過程

一、創建對象的完整過程1. 類加載檢查JVM 遇到 new 指令時&#xff0c;首先去檢查這個類 User 是否已經被加載、解析和初始化過。如果沒有&#xff0c;就先執行 類加載過程&#xff08;加載 .class 文件到方法區/元空間、創建 Class 對象等&#xff09;。【這個過程就是加載、驗…

【Web安全】CRLF注入攻擊深度解析:原理、場景與安全測試防御指南

文章目錄前言&#xff1a;為什么CRLF注入是安全測試不可忽視的威脅&#xff1f;1. CRLF注入核心原理&#xff1a;從字符定義到協議依賴1.1 什么是CRLF&#xff1f;1.2 CRLF在HTTP協議中的關鍵作用1.3 CRLF注入的本質&#xff1a;格式混淆攻擊2. CRLF注入典型利用場景與安全測試…

【安全學習】DVWA 靶場 SQL 注入漏洞原理分析與防御策略(教育用途)

注意&#xff1a;本文內容僅用于合法授權的安全研究、教學演示及漏洞復現&#xff0c;嚴禁用于任何未授權的系統或網絡環境。 所有操作需在本地沙箱或個人可控靶場中執行&#xff0c;切勿對生產環境、他人系統進行測試&#xff0c;非法使用后果自負。&#x1f4cc; 法律與道德雙…

Langflow Memory 技術深度分析

Langflow Memory 技術深度分析 1. Memory 技術概述和設計理念 1.1 技術概述 Langflow 的 Memory 系統是一個多層次的記憶管理框架&#xff0c;專門設計用于處理對話歷史、上下文狀態和會話數據的存儲與檢索。該系統采用了分層架構設計&#xff0c;支持多種記憶類型和存儲后端&a…