Files
Future/Future.Contract/Attributes/ParameterDefine.cs
2025-08-30 17:19:57 +08:00

972 lines
45 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 用于将一个属性标记为一个可以使用参数设计器编辑的参数值
/// </summary>
[DataContract]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class ParameterDefineAttribute : Attribute, INotifyPropertyChanged, IFuture
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 参数的归类信息
/// </summary>
[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"));
}
}
}
/// <summary>
/// 用于存储自定义参数设置器的类型
/// </summary>
[DataMember]
private Type mSetterType = null;
/// <summary>
/// 自定义参数设置器使用的类型定义
/// </summary>
public Type SetterType
{
get => this.mSetterType;
set { this.mSetterType = value; }
}
/// <summary>
/// 用于存储参数数据类型的内部变量
/// </summary>
[DataMember]
private EParameterType mType = EParameterType.Number;
/// <summary>
/// 参数的数据类型
/// </summary>
public EParameterType Type
{
get => this.mType;
set
{
if (this.mType != value)
{
this.mType = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Type"));
}
}
}
/// <summary>
/// 用于存储参数名称的内部变量
/// </summary>
[DataMember]
private string mName = "PName";
/// <summary>
/// 参数的标识名称
/// </summary>
public string Name
{
get => this.mName;
set
{
if (this.mName != value)
{
this.mName = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
/// <summary>
/// 用于存储参数标题名称的内部变量
/// </summary>
[DataMember]
private string mTitle = "动态参数";
/// <summary>
/// 参数的标题
/// </summary>
public string Title
{
get => this.mTitle;
set
{
if (mTitle != value)
{
mTitle = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Title"));
}
}
}
/// <summary>
/// 用于存储参数描述信息的内部变量
/// </summary>
[DataMember]
private string mRemark = "动态参数";
/// <summary>
/// 参数描述
/// </summary>
public string Remark
{
get => this.mRemark;
set
{
if (mRemark != value)
{
mRemark = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Remark"));
}
}
}
/// <summary>
/// 用于存储以文本格式记录的参数默认值的内部变量
/// </summary>
[DataMember]
private string mDefault = "";
/// <summary>
/// 以文本形式存储参数的默认取值或是可取值集合
/// </summary>
public string Default
{
get => this.mDefault;
set
{
if (this.mDefault != value)
{
mDefault = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Default"));
}
}
}
/// <summary>
/// 为设计器指示ValueExp是值还是引用
/// </summary>
public bool IsLinked { get => (this.Expression?.StartsWith(FutureInstruct.PR_StartString)) ?? false; }
/// <summary>
/// 用于存储值表达式的内部变量
/// </summary>
[DataMember]
private string mExpression = "";
/// <summary>
/// 参数引用表达式设计器操作的永远是这个属性而非真正的参数值Value属性
/// </summary>
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"));
}
}
}
/// <summary>
/// 用于存储候选值的内部变量
/// </summary>
[DataMember]
private string mCandidate = "";
/// <summary>
/// 候选值如果类型存在候选值则必须使用标准Json格式描述可以是JsonObject格式或是JsonArray格式的任意一种描述方式
/// </summary>
public string Candidate
{
get => this.mCandidate;
set
{
if (this.mCandidate != value)
{
this.Candidate = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Candidate"));
}
}
}
/// <summary>
/// 候选词字典实例专为设计器使用
/// </summary>
public Dictionary<string, object> CandidateMapping
{
get
{
Dictionary<string, object> dicCandidate = null;
if (!string.IsNullOrEmpty(this.Candidate))
{
try
{
//有可能是JsonArray定义的候选词集合
if (this.Candidate[0] == '[')
{
List<object> list = this.Candidate.Decode4Json<List<object>>();
foreach (var item in list) dicCandidate.Add(item.ToString(), item);
}
//有可能是JsonObject定义的候选词集合
else if (this.Candidate[0] == '{') dicCandidate = this.Candidate.Decode4Json<Dictionary<string, object>>();
//不是有效的Json定义格式
else dicCandidate = new Dictionary<string, object>();
}
catch
{
//Json格式有问题丢弃异常不处理返回一个空的字典以免外部引用时出错
dicCandidate = new Dictionary<string, object>();
}
}
return dicCandidate;
}
}
/// <summary>
/// 是否只允许使用候选值进行选择
/// </summary>
[DataMember]
private bool mIsCandidateOnly = false;
/// <summary>
/// 是否只允许使用候选值进行选择
/// </summary>
public bool IsCandidateOnly
{
get
{
//部分类型此项设置无效,只能使用选择模式
if (this.Type == EParameterType.Boolean) return true;
else return mIsCandidateOnly;
}
set { this.mIsCandidateOnly = value; }
}
/// <summary>
/// 标记一个参数是否允许重新定义,数据类型,参数名称,参数标题,参数描述
/// </summary>
[DataMember]
public bool AllowRefine { get; set; } = false;
/// <summary>
/// 标记参数是否允许重设单位名称
/// </summary>
[DataMember]
public bool AllowReUnit { get; set; } = true;
/// <summary>
/// 参数的单位名称字段
/// </summary>
[DataMember]
private string mUnitName;
/// <summary>
/// 参数的单位名称
/// </summary>
public string UnitName
{
get => this.mUnitName;
set
{
if (this.mUnitName == value) return;
mUnitName = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("UnitName"));
}
}
/// <summary>
/// 标记一个属性是否允许用户编辑
/// </summary>
[DataMember]
public bool IsReadOnly { get; set; } = true;
/// <summary>
/// 设置一个参数的排序,不可为负
/// </summary>
[DataMember]
public int DesignSort { get; set; } = 0;
/// <summary>
/// 参数设计器中显示的参数分组名
/// </summary>
[DataMember]
public string GroupName { get; set; } = "";
public PropertyInfo AttachProperty { get; internal set; }
public object AttachObject { get; internal set; }
/// <summary>
/// 克隆当前对象
/// </summary>
/// <returns>克隆后的对象</returns>
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
};
}
/// <summary>
/// 对象属性覆盖:用引用对象属性覆盖当前对象属性,对引用属性只会实现引用赋值,不做深拷贝
/// </summary>
/// <param name="refer">用于覆盖当前对象属性的源对象</param>
/// <returns>如果源对象类型不是当前对象或是其子类类型则直接覆盖失败返回False</returns>
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;
}
/// <summary>
/// 校验当前参数的设置是否有效;主要校验【Default默认值】、【ValueExp=值表达式】【Candidate候选词】不检查[""]与[null]
/// </summary>
/// <param name="owner">参数归属</param>
/// <returns>如果校验失败则返回错误信息</returns>
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<List<int>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
if (eValue != "")
{
try { eValue.Decode4Json<List<int>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
}
break;
case EParameterType.NumArray://不校验候选值
{
if (dValue != "")
{
try { dValue.Decode4Json<List<double>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
if (eValue != "")
{
try { eValue.Decode4Json<List<double>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
}
break;
case EParameterType.TxtArray:
{
if (dValue != "")
{
try { dValue.Decode4Json<List<string>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
if (eValue != "")
{
try { eValue.Decode4Json<List<string>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“设置值”【 {eValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
}
break;
case EParameterType.ValArray:
{
if (dValue != "")
{
try { dValue.Decode4Json<List<object>>(); }
catch { result.AppendLine($"【{owner}】的参数【{this.Title}】的“默认值”【 {dValue} 】不是有效的“{etypeName}”值请使用标准JsonArray格式设置"); }
}
if (eValue != "")
{
try { eValue.Decode4Json<List<object>>(); }
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;
}
/// <summary>
/// 为一个使用子符串表示的变量变值;注意:不能使用引用表达式,[""]与[null]会返回参数的默认值或C#语言的“类型”默认值!
/// </summary>
/// <param name="sValue">用字符串表示的变量</param>
/// <param name="value">如果成功则存储变量的值</param>
/// <returns>如果失败则返回失败原因,成功则返回“null”</returns>
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<int>();
else
{
try { result = sValue.Decode4Json<List<int>>(); }
catch { sign = false; result = null; }
}
}
break;
case EParameterType.NumArray:
{
if (sValue == "") result = new List<double>();
else
{
try { result = sValue.Decode4Json<List<double>>(); }
catch { sign = false; result = null; }
}
}
break;
case EParameterType.TxtArray:
{
if (sValue == "") result = new List<string>();
else
{
try { result = sValue.Decode4Json<List<string>>(); }
catch { sign = false; result = null; }
}
}
break;
case EParameterType.ValArray:
{
if (sValue == "") result = new List<object>();
else
{
try { result = sValue.Decode4Json<List<object>>(); }
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;
}
}
/// <summary>
/// 获取当前变量的默认值;请使用可空类型接收
/// </summary>
/// <returns>如果未设置则返回该类型的缺省值如果设置错误则返回null</returns>
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<string>();
else
{
try { return sValue.Decode4Json<List<int>>(); }
catch { return null; }
}
}
case EParameterType.NumArray:
{
if (sValue == "") return new List<string>();
else
{
try { return sValue.Decode4Json<List<double>>(); }
catch { return null; }
}
}
case EParameterType.TxtArray:
{
if (sValue == "") return new List<string>();
else
{
try { return sValue.Decode4Json<List<string>>(); }
catch { return null; }
}
}
case EParameterType.ValArray:
{
if (sValue == "") return new List<object>();
else
{
try { return sValue.Decode4Json<List<object>>(); }
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;
}
}
}
}
}
}