using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; namespace Future.Contract { /// /// 用于将一个属性标记为一个可以使用参数设计器编辑的参数值 /// [DataContract] [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class ParameterDefineAttribute : Attribute, INotifyPropertyChanged, IFuture { public event PropertyChangedEventHandler PropertyChanged; /// /// 参数的归类信息 /// [DataMember] private EParameterKind mKind = EParameterKind.General; public EParameterKind Kind { get => this.mKind; set { if (this.mKind != value) { this.mKind = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Kind")); } } } /// /// 用于存储自定义参数设置器的类型 /// [DataMember] private Type mSetterType = null; /// /// 自定义参数设置器使用的类型定义 /// public Type SetterType { get => this.mSetterType; set { this.mSetterType = value; } } /// /// 用于存储参数数据类型的内部变量 /// [DataMember] private EParameterType mType = EParameterType.Number; /// /// 参数的数据类型 /// public EParameterType Type { get => this.mType; set { if (this.mType != value) { this.mType = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Type")); } } } /// /// 用于存储参数名称的内部变量 /// [DataMember] private string mName = "PName"; /// /// 参数的标识名称 /// public string Name { get => this.mName; set { if (this.mName != value) { this.mName = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } /// /// 用于存储参数标题名称的内部变量 /// [DataMember] private string mTitle = "动态参数"; /// /// 参数的标题 /// public string Title { get => this.mTitle; set { if (mTitle != value) { mTitle = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Title")); } } } /// /// 用于存储参数描述信息的内部变量 /// [DataMember] private string mRemark = "动态参数"; /// /// 参数描述 /// public string Remark { get => this.mRemark; set { if (mRemark != value) { mRemark = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Remark")); } } } /// /// 用于存储以文本格式记录的参数默认值的内部变量 /// [DataMember] private string mDefault = ""; /// /// 以文本形式存储参数的默认取值或是可取值集合 /// public string Default { get => this.mDefault; set { if (this.mDefault != value) { mDefault = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Default")); } } } /// /// 为设计器指示ValueExp是值还是引用 /// public bool IsLinked { get => (this.Expression?.StartsWith(FutureInstruct.PR_StartString)) ?? false; } /// /// 用于存储值表达式的内部变量 /// [DataMember] private string mExpression = ""; /// /// 参数引用表达式,设计器操作的永远是这个属性而非真正的参数值Value属性 /// public string Expression { get => this.mExpression; set { if (this.mExpression != value) { this.mExpression = value; this.PropertyChanged(this, new PropertyChangedEventArgs("ValueExp")); this.PropertyChanged(this, new PropertyChangedEventArgs("IsLinked")); } } } /// /// 用于存储候选值的内部变量 /// [DataMember] private string mCandidate = ""; /// /// 候选值:如果类型存在候选值则必须使用标准Json格式描述;可以是JsonObject格式或是JsonArray格式的任意一种描述方式 /// public string Candidate { get => this.mCandidate; set { if (this.mCandidate != value) { this.Candidate = value; this.PropertyChanged(this, new PropertyChangedEventArgs("Candidate")); } } } /// /// 候选词字典实例专为设计器使用 /// public Dictionary CandidateMapping { get { Dictionary dicCandidate = null; if (!string.IsNullOrEmpty(this.Candidate)) { try { //有可能是JsonArray定义的候选词集合 if (this.Candidate[0] == '[') { List list = this.Candidate.Decode4Json>(); foreach (var item in list) dicCandidate.Add(item.ToString(), item); } //有可能是JsonObject定义的候选词集合 else if (this.Candidate[0] == '{') dicCandidate = this.Candidate.Decode4Json>(); //不是有效的Json定义格式 else dicCandidate = new Dictionary(); } catch { //Json格式有问题;丢弃异常,不处理;返回一个空的字典,以免外部引用时出错 dicCandidate = new Dictionary(); } } return dicCandidate; } } /// /// 是否只允许使用候选值进行选择 /// [DataMember] private bool mIsCandidateOnly = false; /// /// 是否只允许使用候选值进行选择 /// public bool IsCandidateOnly { get { //部分类型此项设置无效,只能使用选择模式 if (this.Type == EParameterType.Boolean) return true; else return mIsCandidateOnly; } set { this.mIsCandidateOnly = value; } } /// /// 标记一个参数是否允许重新定义,数据类型,参数名称,参数标题,参数描述 /// [DataMember] public bool AllowRefine { get; set; } = false; /// /// 标记参数是否允许重设单位名称 /// [DataMember] public bool AllowReUnit { get; set; } = true; /// /// 参数的单位名称字段 /// [DataMember] private string mUnitName; /// /// 参数的单位名称 /// public string UnitName { get => this.mUnitName; set { if (this.mUnitName == value) return; mUnitName = value; this.PropertyChanged(this, new PropertyChangedEventArgs("UnitName")); } } /// /// 标记一个属性是否允许用户编辑 /// [DataMember] public bool IsReadOnly { get; set; } = true; /// /// 设置一个参数的排序,不可为负 /// [DataMember] public int DesignSort { get; set; } = 0; /// /// 参数设计器中显示的参数分组名 /// [DataMember] public string GroupName { get; set; } = ""; public PropertyInfo AttachProperty { get; internal set; } public object AttachObject { get; internal set; } /// /// 克隆当前对象 /// /// 克隆后的对象 public IFuture Clone() { return new ParameterDefineAttribute() { Name = this.Name, AllowRefine = this.AllowRefine, AllowReUnit = this.AllowReUnit, AttachObject = this.AttachObject, AttachProperty = this.AttachProperty, Default = this.Default, DesignSort = this.DesignSort, GroupName = this.GroupName, IsReadOnly = this.IsReadOnly, Kind = this.Kind, Remark = this.Remark, Title = this.Title, Type = this.Type, UnitName = this.UnitName, Expression = this.Expression }; } /// /// 对象属性覆盖:用引用对象属性覆盖当前对象属性,对引用属性只会实现引用赋值,不做深拷贝 /// /// 用于覆盖当前对象属性的源对象 /// 如果源对象类型不是当前对象或是其子类类型则直接覆盖失败,返回False public bool Cover(IFuture refer) { if (refer == null) return false; ParameterDefineAttribute pda = refer as ParameterDefineAttribute; if (pda == null) return false; this.Name = pda.Name; this.AllowRefine = pda.AllowRefine; this.AllowRefine = pda.AllowRefine; this.AttachObject = pda.AttachObject; this.AttachProperty = pda.AttachProperty; this.Default = pda.Default; this.DesignSort = pda.DesignSort; this.GroupName = pda.GroupName; this.IsReadOnly = pda.IsReadOnly; this.Kind = pda.Kind; this.Remark = pda.Remark; this.Title = pda.Title; this.Type = pda.Type; this.UnitName = pda.UnitName; this.Expression = pda.Expression; return true; } /// /// 校验当前参数的设置是否有效;主要校验【Default:默认值】、【ValueExp=值表达式】【Candidate:候选词】;不检查[""]与[null] /// /// 参数归属 /// 如果校验失败则返回错误信息 public string Verify(string owner = null) { EParameterType type = this.Type; string ownerName = owner ?? (this.AttachObject as IConfigurableObject)?.Title; string etypeName = type.GetParameterTypeName(); string eValue = this.mExpression ?? ""; string dValue = this.mDefault ?? ""; string cValue = this.mCandidate ?? ""; StringBuilder result = new StringBuilder(); switch (type) { case EParameterType.Boolean: { bool sign = true; bool value = false; //检查默认值表达式,忽略空值[null]与[""] if (dValue != "") { sign = bool.TryParse(dValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请重新设置!"); } //检查实际值表达式,忽略空值[null]与[""]和上下文引用表达式 if (eValue != "" && !eValue.StartsWith(FutureInstruct.PR_StartString)) { sign = bool.TryParse(eValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【{eValue}】不是有效的“{etypeName}”值;请重新设置!"); } //检查候选词表达式,忽略空值[null]与[""] if (cValue != "" && this.CandidateMapping.Count == 0) result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合【{cValue}】格式不是有效的“非空”JsonArray或JsonObject格式!"); else { foreach (object cval in this.CandidateMapping.Values) { if (!(cval is bool)) { result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合中存在非布尔值【{(cval?.ToString()) ?? ""}】;请重新设置!"); break; } } } } break; case EParameterType.DateTime: { bool sign = true; DateTime value = DateTime.MinValue; if (dValue != "") { sign = DateTime.TryParse(dValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请重新设置!"); } if (eValue != "" && !eValue.StartsWith(FutureInstruct.PR_StartString)) { sign = DateTime.TryParse(eValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【{eValue}】不是有效的“{etypeName}”值;请重新设置!"); } if (cValue != "" && this.CandidateMapping.Count == 0) result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合【{cValue}】格式不是有效的“非空”JsonArray或JsonObject格式!"); else { foreach (object cval in this.CandidateMapping.Values) { if (!(cval is DateTime)) { result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合中存在非布尔值【{(cval?.ToString()) ?? ""}】;请重新设置!"); break; } } } } break; case EParameterType.Enums: { bool sign = true; int value = 0; if (dValue != "") { sign = int.TryParse(dValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请重新设置!"); } if (eValue != "" && eValue.StartsWith(FutureInstruct.PR_StartString)) { sign = int.TryParse(eValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【{eValue}】不是有效的“{etypeName}”值;请重新设置!"); } if (cValue != "" && this.CandidateMapping.Count == 0) result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合【{cValue}】格式不是有效的“非空”JsonArray或JsonObject格式!"); else { foreach (object cval in this.CandidateMapping.Values) { if (!(cval is int)) { result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合中存在非布尔值【{(cval?.ToString()) ?? ""}】;请重新设置!"); break; } } } } break; case EParameterType.Integer: { bool sign = true; int value = 0; if (dValue != "") { sign = int.TryParse(dValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请重新设置!"); } if (eValue != "" && eValue.StartsWith(FutureInstruct.PR_StartString)) { sign = int.TryParse(eValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【{eValue}】不是有效的“{etypeName}”值;请重新设置!"); } if (cValue != "" && this.CandidateMapping.Count == 0) result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合【{cValue}】格式不是有效的“非空”JsonArray或JsonObject格式!"); else { foreach (object cval in this.CandidateMapping.Values) { if (!(cval is int)) { result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合中存在非布尔值【{(cval?.ToString()) ?? ""}】;请重新设置!"); break; } } } } break; case EParameterType.Number: { bool sign = true; double value = 0; if (dValue != "") { sign = double.TryParse(dValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请重新设置!"); } if (eValue != "" && eValue.StartsWith(FutureInstruct.PR_StartString)) { sign = double.TryParse(eValue, out value); if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【{eValue}】不是有效的“{etypeName}”值;请重新设置!"); } if (cValue != "" && this.CandidateMapping.Count == 0) result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合【{cValue}】格式不是有效的“非空”JsonArray或JsonObject格式!"); else { foreach (object cval in this.CandidateMapping.Values) { if (!(cval is double)) { result.AppendLine($"【{owner}】的参数【{this.Title}】的“候选值”集合中存在非布尔值【{(cval?.ToString()) ?? ""}】;请重新设置!"); break; } } } } break; case EParameterType.String: { } break;//不校验 case EParameterType.RichText: { } break;//不校验 case EParameterType.Variant: { } break;//不校验 case EParameterType.IntArray://不校验候选值 { if (dValue != "") { try { dValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } if (eValue != "") { try { eValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } } break; case EParameterType.NumArray://不校验候选值 { if (dValue != "") { try { dValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } if (eValue != "") { try { eValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } } break; case EParameterType.TxtArray: { if (dValue != "") { try { dValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } if (eValue != "") { try { eValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } } break; case EParameterType.ValArray: { if (dValue != "") { try { dValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } if (eValue != "") { try { eValue.Decode4Json>(); } catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值;请使用标准JsonArray格式设置!"); } } } break; default://暂时先不校验候选值 { if (dValue != "") { dValue = dValue.ToUpper(); if (dValue.StartsWith("0X")) dValue = dValue.Substring(2); bool sign = true; foreach (char c in dValue) { if (c < 48 || c > 70 || (c > 57 && c < 65)) { sign = false; break; } } if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值;请使用标准16进制字符串表示!"); } if (eValue != "") { eValue = eValue.ToUpper(); if (eValue.StartsWith("0X")) eValue = eValue.Substring(2); bool sign = true; foreach (char c in eValue) { if (c < 48 || c > 70 || (c > 57 && c < 65)) { sign = false; break; } } if (!sign) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值;请使用标准16进制字符串表示!"); } switch (type) { case EParameterType.Byte: { if (dValue != "" && dValue.Length != 2) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】应该是“0x”引导的{2}位16进制数,例如“0xA1”!"); if (eValue != "" && eValue.Length != 2) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】应该是“0x”引导的{2}位16进制数,例如“0xA1”!"); } break; case EParameterType.Word: { if (dValue != "" && dValue.Length != 4) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】应该是“0x”引导的{4}位16进制数,例如“0xA123”!"); if (eValue != "" && eValue.Length != 4) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】应该是“0x”引导的{4}位16进制数,例如“0xA123”!"); } break; case EParameterType.DWord: { if (dValue != "" && dValue.Length != 4) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】应该是“0x”引导的{4}位16进制数,例如“0xA1234567”!"); if (eValue != "" && eValue.Length != 8) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】应该是“0x”引导的{8}位16进制数,例如“0xA1234567”!"); } break; case EParameterType.LWord: { if (dValue != "" && dValue.Length != 4) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】应该是“0x”引导的{4}位16进制数,例如“0x0123456789ABCDEF”!"); if (eValue != "" && eValue.Length != 16) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】应该是“0x”引导的{16}位16进制数,例如“0x0123456789ABCDEF”!"); } break; case EParameterType.ByteArray: { if (dValue != "" && dValue.Length != 4) result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】应该是“0x”引导的{4}位16进制数,例如“0xAAFF00”!"); if (eValue != "" && ((eValue.Length % 2) != 0)) result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】应该是“0x”偶数个16进制数,例如“0xAAFF00”!"); } break; default: break; } } break; } string strBuffer = result.ToString(); return string.IsNullOrEmpty(strBuffer) ? null : strBuffer; } /// /// 为一个使用子符串表示的变量变值;注意:不能使用引用表达式,[""]与[null]会返回参数的默认值或C#语言的“类型”默认值! /// /// 用字符串表示的变量 /// 如果成功则存储变量的值 /// 如果失败则返回失败原因,成功则返回“null” public string Evaluate(string sValue, out object value) { EParameterType type = this.Type; sValue = string.IsNullOrWhiteSpace(sValue) ? (string.IsNullOrWhiteSpace(this.Default) ? "" : this.Default) : sValue; if (sValue.StartsWith(FutureInstruct.PR_StartString)) { value = null; return $"请先从上下文中获取引用表达式【{sValue}】的值表式再进行求值操作!"; } string typeName = type.GetParameterTypeName(); string ownerName = ((this.AttachObject as IConfigurableObject)?.Title) ?? "???"; bool sign = true; object result = null; StringBuilder strBuilder = new StringBuilder(); //根据不同的参数类型进行不同的求值逻辑; switch (type) { case EParameterType.Boolean: { bool oValue = false; sign = bool.TryParse(sValue, out oValue); result = oValue; } break; case EParameterType.DateTime: { DateTime oValue = DateTime.Now; sign = DateTime.TryParse(sValue, out oValue); result = oValue; } break; case EParameterType.Enums: { int oValue = 0; sign = int.TryParse(sValue, out oValue); result = oValue; } break;//需要检查候选值 case EParameterType.Integer: { int oValue = 0; sign = int.TryParse(sValue, out oValue); result = oValue; } break;//需要检查候选值 case EParameterType.Number: { double oValue = 0; sign = double.TryParse(sValue, out oValue); result = oValue; } break;//需要检查候选值 case EParameterType.String: { result = sValue; } break;//需要检查候选值 case EParameterType.RichText: { result = sValue; } break; case EParameterType.Variant: { result = sValue; } break; case EParameterType.IntArray: { if (sValue == "") result = new List(); else { try { result = sValue.Decode4Json>(); } catch { sign = false; result = null; } } } break; case EParameterType.NumArray: { if (sValue == "") result = new List(); else { try { result = sValue.Decode4Json>(); } catch { sign = false; result = null; } } } break; case EParameterType.TxtArray: { if (sValue == "") result = new List(); else { try { result = sValue.Decode4Json>(); } catch { sign = false; result = null; } } } break; case EParameterType.ValArray: { if (sValue == "") result = new List(); else { try { result = sValue.Decode4Json>(); } catch { sign = false; result = null; } } } break;//需要检查候选值 default://所有不同长度的字节码类型 { string hxValue = sValue ?? ""; hxValue = hxValue.Trim().ToUpper(); if (hxValue.Length > 1 && hxValue.StartsWith("0X")) hxValue = hxValue.Substring(2); foreach (char c in hxValue) { if (c < 48 || c > 70 || (c > 57 && c < 65)) { sign = false; break; } } if (!sign) result = null; else { switch (this.Type) { case EParameterType.Byte: { if (hxValue.Length < 2) hxValue.PadLeft(2, '0'); else hxValue = hxValue.Substring(hxValue.Length - 2); } break; case EParameterType.Word: { if (hxValue.Length < 4) hxValue.PadLeft(4, '0'); else hxValue = hxValue.Substring(hxValue.Length - 4); } break; case EParameterType.DWord: { if (hxValue.Length < 8) hxValue.PadLeft(8, '0'); else hxValue = hxValue.Substring(hxValue.Length - 8); } break; case EParameterType.LWord: { if (hxValue.Length < 16) hxValue.PadLeft(16, '0'); else hxValue = hxValue.Substring(hxValue.Length - 16); } break; case EParameterType.ByteArray: { if ((hxValue.Length % 2) != 0) hxValue = $"0{hxValue}"; } break; default: break; } byte[] bytes = new byte[hxValue.Length / 2]; for (int i = 0; i < bytes.Length; i++) { string vhx = hxValue.Substring(i * 2, 2); bytes[i] = Convert.ToByte(vhx, 16); } result = bytes; } } break; } value = result; if (sign) return null; else { string strBuffer = strBuilder.ToString(); return string.IsNullOrEmpty(strBuffer) ? null : strBuffer; } } /// /// 获取当前变量的默认值;请使用可空类型接收 /// /// 如果未设置则返回该类型的缺省值,如果设置错误则返回null public object GetDefault() { EParameterType type = this.Type; string sValue = this.Default ?? ""; switch (type) { case EParameterType.Boolean: { if (sValue == "") return false; bool result = false; bool sign = bool.TryParse(sValue, out result); if (sign) return result; else return null; } case EParameterType.DateTime: { if (sValue == "") return DateTime.Now; DateTime result = DateTime.Now; bool sign = DateTime.TryParse(sValue, out result); if (sign) return result; else return null; } case EParameterType.Enums: //本质上是Int { if (sValue == "") return default(EParameterType); int result = 0; bool sign = int.TryParse(sValue, out result); if (sign) return result; else return null; } case EParameterType.Integer: { if (sValue == "") return default(EParameterType); int result = 0; bool sign = int.TryParse(sValue, out result); if (sign) return result; else return null; } case EParameterType.Number: { if (sValue == "") return default(EParameterType); double result = 0; bool sign = double.TryParse(sValue, out result); if (sign) return result; else return null; } case EParameterType.String: return sValue; case EParameterType.RichText: return sValue; case EParameterType.Variant: return sValue; case EParameterType.IntArray: { if (sValue == "") return new List(); else { try { return sValue.Decode4Json>(); } catch { return null; } } } case EParameterType.NumArray: { if (sValue == "") return new List(); else { try { return sValue.Decode4Json>(); } catch { return null; } } } case EParameterType.TxtArray: { if (sValue == "") return new List(); else { try { return sValue.Decode4Json>(); } catch { return null; } } } case EParameterType.ValArray: { if (sValue == "") return new List(); else { try { return sValue.Decode4Json>(); } catch { return null; } } } default: { string hxValue = sValue ?? ""; hxValue = hxValue.Trim().ToUpper(); if (hxValue.Length > 1 && hxValue.StartsWith("0X")) hxValue = hxValue.Substring(2); bool sign = true; foreach (char c in hxValue) { if (c < 48 || c > 70 || (c > 57 && c < 65)) { sign = false; break; } } //如果不是有效的16进制字符串则直接返回null if (!sign) return null; else { switch (type) { case EParameterType.Byte: { if (hxValue.Length < 2) hxValue.PadLeft(2, '0'); else hxValue = hxValue.Substring(hxValue.Length - 2); } break; case EParameterType.Word: { if (hxValue.Length < 4) hxValue.PadLeft(4, '0'); else hxValue = hxValue.Substring(hxValue.Length - 4); } break; case EParameterType.DWord: { if (hxValue.Length < 8) hxValue.PadLeft(8, '0'); else hxValue = hxValue.Substring(hxValue.Length - 8); } break; case EParameterType.LWord: { if (hxValue.Length < 16) hxValue.PadLeft(16, '0'); else hxValue = hxValue.Substring(hxValue.Length - 16); } break; case EParameterType.ByteArray: { if ((hxValue.Length % 2) != 0) hxValue = $"0{hxValue}"; } break; default: break; } byte[] bytes = new byte[hxValue.Length / 2]; for (int i = 0; i < bytes.Length; i++) { string vhx = hxValue.Substring(i * 2, 2); bytes[i] = Convert.ToByte(vhx, 16); } return bytes; } } } } } }