using System.Collections; using System.Dynamic; using System.Reflection; using System.Runtime.Serialization.Json; using System.Text; using Masuit.Tools; using System.Xml.Linq; using System.Xml; using System.Text.Json; namespace EasyTemplate.Tool; public sealed class Clay : DynamicObject, IEnumerable { // // 摘要: // JSON 类型 private enum JsonType { @string, number, boolean, @object, array, @null } // // 摘要: // JSON 类型 private readonly JsonType jsonType; // // 摘要: // 校验 Xml 标签格式 private static readonly Func TryVerifyNCName = (Func)Delegate.CreateDelegate(typeof(Func), typeof(XmlConvert).GetMethod("TryVerifyNCName", BindingFlags.Static | BindingFlags.NonPublic)); // // 摘要: // 将被转换成字符串的类型 private static readonly Type[] ToBeConvertStringTypes = new Type[1] { typeof(DateTimeOffset) }; // // 摘要: // 是否是 Object 类型 public bool IsObject => jsonType == JsonType.@object; // // 摘要: // 是否是 Array 类型 public bool IsArray => jsonType == JsonType.array; // // 摘要: // 粘土对象 Xml 元数据 public XElement XmlElement { get; private set; } // // 摘要: // 当 Clay 时 数组类型时的长度 public int Length => XmlElement.Elements().Count(); // // 摘要: // 配置读取不存在 Key 时行为 // // 言论: // 如果设置 false,那么返回 null public bool ThrowOnUndefined { get; set; } = true; // // 摘要: // 构造函数 // // 参数: // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true public Clay(bool throwOnUndefined = true) { XmlElement = new XElement("root", CreateTypeAttr(JsonType.@object)); jsonType = JsonType.@object; ThrowOnUndefined = throwOnUndefined; } // // 摘要: // 构造函数 // // 参数: // element: // System.Xml.Linq.XElement // // type: // JSON 类型 // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true private Clay(XElement element, JsonType type, bool throwOnUndefined = true) { XmlElement = element; jsonType = type; ThrowOnUndefined = throwOnUndefined; } // // 摘要: // 创建空的粘土对象 // // 参数: // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Object(bool throwOnUndefined = true) { return new Clay(throwOnUndefined); } // // 摘要: // 基于现有对象创建粘土对象 // // 参数: // obj: // 对象 // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Object(object obj, bool throwOnUndefined = true) { if (obj == null) { throw new ArgumentNullException("obj"); } return Parse(CreateJsonString(new XStreamingElement("root", CreateTypeAttr(GetJsonType(obj)), CreateJsonNode(obj))), throwOnUndefined); } // // 摘要: // 基于现有对象创建粘土对象 // // 参数: // json: // JSON 字符串 // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Parse(string json, bool throwOnUndefined = true) { return Parse(json, Encoding.UTF8, throwOnUndefined); } // // 摘要: // 基于现有对象创建粘土对象 // // 参数: // json: // JSON 字符串 // // encoding: // 编码类型 // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Parse(string json, Encoding encoding, bool throwOnUndefined = true) { using XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(encoding.GetBytes(json), XmlDictionaryReaderQuotas.Max); return ToValue(XElement.Load(reader), throwOnUndefined); } // // 摘要: // 基于 Stream 对象创建粘土对象 // // 参数: // stream: // System.IO.Stream // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Parse(Stream stream, bool throwOnUndefined = true) { using XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); return ToValue(XElement.Load(reader), throwOnUndefined); } // // 摘要: // 基于 Stream 对象创建粘土对象 // // 参数: // stream: // System.IO.Stream // // encoding: // 编码类型 // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true // // 返回结果: // Furion.ClayObject.Clay public static dynamic Parse(Stream stream, Encoding encoding, bool throwOnUndefined = true) { using XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(stream, encoding, XmlDictionaryReaderQuotas.Max, delegate { }); return ToValue(XElement.Load(reader), throwOnUndefined); } // // 摘要: // 重写动态调用方法实现删除行为 // // 参数: // binder: // // args: // // result: public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { result = (IsArray ? Delete((int)args[0]) : Delete((string)args[0])); return true; } // // 摘要: // 重写动态调用成员名称方法实现键是否存在行为 // // 参数: // binder: // // args: // // result: public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { if (args.Length != 0) { result = null; return false; } result = IsDefined(binder.Name); return true; } // // 摘要: // 重写类型转换方法实现粘土对象动态转换 // // 参数: // binder: // // result: public override bool TryConvert(ConvertBinder binder, out object result) { if (binder.Type == typeof(IEnumerable) || binder.Type == typeof(object[])) { IEnumerable enumerable = (IEnumerable)(IsArray ? ((IEnumerable)(from x in XmlElement.Elements() select ToValue(x, ThrowOnUndefined))) : ((IEnumerable)XmlElement.Elements().Select((Func)((XElement x) => new KeyValuePair((x.Name == "{item}item") ? x.Attribute("item").Value : x.Name.LocalName, ToValue(x, ThrowOnUndefined)))))); IEnumerable enumerable2; if (!(binder.Type == typeof(object[]))) { enumerable2 = enumerable; } else { IEnumerable enumerable3 = enumerable.ToArray(); enumerable2 = enumerable3; } result = enumerable2; } else { result = Deserialize(binder.Type); } return true; } // // 摘要: // 重写根据索引获取值的行为 // // 参数: // binder: // // indexes: // // result: public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { bool isValid; if (!IsArray) { return TryGet(FindXElement((string)indexes[0], out isValid), out result, ThrowOnUndefined); } return TryGet(XmlElement.Elements().ElementAtOrDefault((int)indexes[0]), out result, ThrowOnUndefined); } // // 摘要: // 重写根据成员名称获取值的行为 // // 参数: // binder: // // result: public override bool TryGetMember(GetMemberBinder binder, out object result) { bool isValid; if (!IsArray) { return TryGet(FindXElement(binder.Name, out isValid), out result, ThrowOnUndefined); } return TryGet(XmlElement.Elements().ElementAtOrDefault(int.Parse(binder.Name)), out result, ThrowOnUndefined); } // // 摘要: // 重写根据索引设置值的行为 // // 参数: // binder: // // indexes: // // value: public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) { if (!IsArray) { return TrySet((string)indexes[0], value); } return TrySet((int)indexes[0], value); } // // 摘要: // 重写根据成员名称设置值的行为 // // 参数: // binder: // // value: public override bool TrySetMember(SetMemberBinder binder, object value) { if (!IsArray) { return TrySet(binder.Name, value); } return TrySet(int.Parse(binder.Name), value); } // // 摘要: // 重写获取所有动态成员名称行为 public override IEnumerable GetDynamicMemberNames() { if (!IsArray) { return from x in XmlElement.Elements() select (!(x.Name == "{item}item")) ? x.Name.LocalName : x.Attribute("item").Value; } return XmlElement.Elements().Select((XElement x, int i) => i.ToString()); } // // 摘要: // 重写转换成字符串方法 public override string ToString() { foreach (XElement item in from x in XmlElement.Descendants() where x.Attribute("type").Value == "null" select x) { item.RemoveNodes(); } return CreateJsonString(new XStreamingElement("root", CreateTypeAttr(jsonType), XmlElement.Elements())); } // // 摘要: // 判断对象键是否存在 // // 参数: // name: public bool IsDefined(string name) { bool isValid; if (IsObject) { return FindXElement(name, out isValid) != null; } return false; } // // 摘要: // 判断数组索引是否存在 // // 参数: // index: public bool IsDefined(int index) { if (IsArray) { return XmlElement.Elements().ElementAtOrDefault(index) != null; } return false; } // // 摘要: // 根据键删除对象属性 // // 参数: // name: public bool Delete(string name) { bool isValid; XElement xElement = FindXElement(name, out isValid); if (xElement != null) { xElement.Remove(); return true; } return false; } // // 摘要: // 根据索引删除数组元素 // // 参数: // index: public bool Delete(int index) { XElement xElement = XmlElement.Elements().ElementAtOrDefault(index); if (xElement != null) { xElement.Remove(); return true; } return false; } // // 摘要: // 将粘土对象反序列化为特定类型 // // 类型参数: // T: public T Deserialize() { return (T)Deserialize(typeof(T)); } // // 摘要: // 将粘土对象转换为 object 类型 public object Solidify() { return Solidify(); } // // 摘要: // 将粘土对象转换为特定类型 // // 类型参数: // T: public T Solidify() { //return JSON.Deserialize(ToString()); return ToString().ToEntity(); } // // 摘要: // 将粘土对象转换为字典类型 public IDictionary ToDictionary() { if (IsArray) { throw new InvalidOperationException("Cannot convert a clay object with JsonType as an array to a dictionary object."); } Dictionary dictionary = new Dictionary(); IEnumerator enumerator = GetEnumerator(); try { while (enumerator.MoveNext()) { KeyValuePair keyValuePair = (KeyValuePair)enumerator.Current; dictionary[keyValuePair.Key] = keyValuePair.Value; } return dictionary; } finally { IDisposable disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } } } // // 摘要: // 转换成特定对象 // // 参数: // valueProvider: // 值提供器 // // 类型参数: // T: public IEnumerable ConvertTo(Func valueProvider = null) where T : class, new() { IEnumerable enumerable = from p in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public) where p.CanWrite select p; List list = new List(); if (IsObject) { list.Add(ConvertTo(enumerable, (dynamic)this, valueProvider)); return list; } if (IsArray) { foreach (dynamic item in AsEnumerator()) { list.Add(ConvertTo(enumerable, item, valueProvider)); } } return list; } // // 摘要: // 将粘土对象转换为特定类型 // // 参数: // properties: // // clay: // // valueProvider: // 值提供器 // // 类型参数: // T: private static T ConvertTo(IEnumerable properties, dynamic clay, Func valueProvider = null) where T : class, new() { T val = new T(); foreach (PropertyInfo property in properties) { object obj = ((clay.IsDefined(property.Name)) ? clay[property.Name] : null); if (valueProvider != null) { obj = valueProvider(property, obj); } property.SetValue(val, obj.ChangeType(property.PropertyType)); } return val; } // // 摘要: // XElement 对象转换成 C# 对象 // // 参数: // element: // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true private static dynamic ToValue(XElement element, bool throwOnUndefined = true) { JsonType jsonType = (JsonType)Enum.Parse(typeof(JsonType), element.Attribute("type").Value); switch (jsonType) { case JsonType.boolean: return (bool)element; case JsonType.number: if (element.Value.Contains('.')) { return (double)element; } return (long)element; case JsonType.@string: return (string?)element; case JsonType.@object: case JsonType.array: return new Clay(element, jsonType, throwOnUndefined); default: return null; } } // // 摘要: // 获取 JSON 类型 // // 参数: // obj: private static JsonType GetJsonType(object obj) { if (obj == null) { return JsonType.@null; } Type type = obj.GetType(); if (ToBeConvertStringTypes.Contains(type)) { return JsonType.@string; } if (obj is ExpandoObject) { return JsonType.@object; } switch (Type.GetTypeCode(type)) { case TypeCode.Boolean: return JsonType.boolean; case TypeCode.Char: case TypeCode.DateTime: case TypeCode.String: return JsonType.@string; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return JsonType.number; case TypeCode.Object: return (obj is IEnumerable) ? JsonType.array : JsonType.@object; default: return JsonType.@null; } } // // 摘要: // 创建 XElement type 属性 // // 参数: // type: private static XAttribute CreateTypeAttr(JsonType type) { return new XAttribute("type", type.ToString()); } // // 摘要: // 创建 XElement 节点值 // // 参数: // obj: private static object CreateJsonNode(object obj) { bool flag = obj?.GetType().IsEnum ?? false; switch (GetJsonType(obj)) { case JsonType.@string: case JsonType.number: return flag ? ((object)(int)obj) : obj; case JsonType.boolean: return obj.ToString().ToLower(); case JsonType.@object: return CreateXObject(obj); case JsonType.array: return CreateXArray(obj as IEnumerable); default: return null; } } // // 摘要: // 创建 XStreamingElement 对象 // // 参数: // obj: // // 类型参数: // T: private static IEnumerable CreateXArray(T obj) where T : IEnumerable { return from object o in obj select new XStreamingElement("item", CreateTypeAttr(GetJsonType(o)), CreateJsonNode(o)); } // // 摘要: // 创建 XStreamingElement 对象 // // 参数: // obj: private static IEnumerable CreateXObject(object obj) { if (obj is ExpandoObject source) { return source.Select, XStreamingElement>((KeyValuePair a) => new XStreamingElement(a.Key, CreateTypeAttr(GetJsonType(a.Value)), CreateJsonNode(a.Value))); } return from pi in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) select new { Name = pi.Name, Value = pi.GetValue(obj, null) } into a select new XStreamingElement(a.Name, CreateTypeAttr(GetJsonType(a.Value)), CreateJsonNode(a.Value)); } // // 摘要: // 创建 JSON 字符串 // // 参数: // element: private static string CreateJsonString(XStreamingElement element) { using MemoryStream memoryStream = new MemoryStream(); using XmlDictionaryWriter xmlDictionaryWriter = JsonReaderWriterFactory.CreateJsonWriter(memoryStream, Encoding.UTF8); element.WriteTo(xmlDictionaryWriter); xmlDictionaryWriter.Flush(); return Encoding.UTF8.GetString(memoryStream.ToArray()); } // // 摘要: // 读取值 // // 参数: // element: // // result: // // throwOnUndefined: private static bool TryGet(XElement element, out object result, bool throwOnUndefined = true) { if (element == null) { result = null; return !throwOnUndefined; } result = ToValue(element, throwOnUndefined); return true; } // // 摘要: // 根据键设置对象值 // // 参数: // name: // // value: private bool TrySet(string name, object value) { JsonType jsonType = GetJsonType(value); if (value is Clay clay) { if (clay.IsObject) { value = value.ToExpandoObject(); } else if (clay.IsArray) { List list = new List(); foreach (object item in (dynamic)clay) { list.Add((dynamic)((item is Clay value2) ? value2.ToExpandoObject() : item)); } value = list; } } bool isValid; XElement xElement = FindXElement(name, out isValid); if (xElement == null) { if (isValid) { XmlElement.Add(new XElement(name, CreateTypeAttr(jsonType), CreateJsonNode(value))); } else { XElement xElement2 = XElement.Parse($""); xElement2.ReplaceNodes(CreateJsonNode(value)); XmlElement.Add(xElement2); } } else { xElement.Attribute("type").Value = jsonType.ToString(); xElement.ReplaceNodes(CreateJsonNode(value)); } return true; } // // 摘要: // 根据索引设置数组值 // // 参数: // index: // // value: private bool TrySet(int index, object value) { JsonType type = GetJsonType(value); XElement xElement = XmlElement.Elements().ElementAtOrDefault(index); if (xElement == null) { XmlElement.Add(new XElement("item", CreateTypeAttr(type), CreateJsonNode(value))); } else { xElement.Attribute("type").Value = type.ToString(); xElement.ReplaceNodes(CreateJsonNode(value)); } return true; } // // 摘要: // 反序列化 // // 参数: // type: private object Deserialize(Type type) { if (!IsArray) { return DeserializeObject(type); } return DeserializeArray(type); } // // 摘要: // 反序列化对象 // // 参数: // targetType: private object DeserializeObject(Type targetType) { object obj = Activator.CreateInstance(targetType); Dictionary dictionary = (from p in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public) where p.CanWrite select p).ToDictionary((PropertyInfo pi) => pi.Name, (PropertyInfo pi) => pi); foreach (XElement item in XmlElement.Elements()) { string key = ((item.Name == "{item}item") ? item.Attribute("item").Value : item.Name.LocalName); if (dictionary.TryGetValue(key, out var value)) { dynamic val = DeserializeValue(item, value.PropertyType, ThrowOnUndefined); value.SetValue(obj, val, null); } } return obj; } // // 摘要: // 反序列化值 // // 参数: // element: // // elementType: // // throwOnUndefined: // 如果设置 false,则读取不存在的值返回 null,默认 true private static dynamic DeserializeValue(XElement element, Type elementType, bool throwOnUndefined = true) { dynamic val = ToValue(element, throwOnUndefined); if (val is Clay clay) { val = clay.Deserialize(elementType); } return Extension.ChangeType(val, elementType); } // // 摘要: // 反序列化数组 // // 参数: // targetType: private object DeserializeArray(Type targetType) { if (targetType.IsArray) { Type elementType = targetType.GetElementType(); dynamic val = Array.CreateInstance(elementType, XmlElement.Elements().Count()); int num = 0; { foreach (XElement item in XmlElement.Elements()) { val[num++] = DeserializeValue(item, elementType, ThrowOnUndefined); } return val; } } Type elementType2 = targetType.GetGenericArguments()[0]; dynamic val2 = Activator.CreateInstance(targetType); foreach (XElement item2 in XmlElement.Elements()) { val2.Add(DeserializeValue(item2, elementType2, ThrowOnUndefined)); } return val2; } // // 摘要: // 根据键查找 System.Xml.Linq.XElement 对象 // // 参数: // name: // // isValid: private XElement FindXElement(string name, out bool isValid) { bool flag = (isValid = TryVerifyNCName(name) == null); XElement? xElement = (from e in XmlElement.Elements("{item}item") where (string?)e.Attribute("item") == name select e).FirstOrDefault(); if (xElement == null) { if (!flag) { return null; } xElement = XmlElement.Element(name); } return xElement; } // // 摘要: // 初始化粘土对象枚举器 public IEnumerator GetEnumerator() { if (!IsArray) { return new ClayObjectEnumerator(this); } return new ClayArrayEnumerator(this); } // // 摘要: // 将粘土对象转换成 IEnumerable{T} 对象 public IEnumerable AsEnumerator() { return this.Cast(); } // // 摘要: // 内部粘土对象枚举器 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public static class ExpandoObjectExtensions { // // 摘要: // 将对象转 ExpandoObject 类型 // // 参数: // value: public static ExpandoObject ToExpandoObject(this object value) { if (value == null) { throw new ArgumentNullException("value"); } if (value is Clay clay && clay.IsObject) { dynamic val = new ExpandoObject(); IDictionary dictionary = (IDictionary)val; foreach (object item in (dynamic)clay) { KeyValuePair keyValuePair = (KeyValuePair)(dynamic)item; dictionary.Add(keyValuePair.Key, (dynamic)((keyValuePair.Value is Clay value2) ? value2.ToExpandoObject() : keyValuePair.Value)); } return val; } if (value is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Object) { dynamic val2 = new ExpandoObject(); IDictionary dictionary2 = (IDictionary)val2; foreach (KeyValuePair item2 in jsonElement.ToObject() as IDictionary) { dictionary2.Add(item2); } return val2; } ExpandoObject expandoObject = value as ExpandoObject; if (expandoObject == null) { expandoObject = new ExpandoObject(); IDictionary dictionary3 = expandoObject; foreach (KeyValuePair item3 in value.ToDictionary()) { dictionary3.Add(item3); } } return expandoObject; } // // 摘要: // 移除 ExpandoObject 对象属性 // // 参数: // expandoObject: // // propertyName: public static void RemoveProperty(this ExpandoObject expandoObject, string propertyName) { if (expandoObject == null) { throw new ArgumentNullException("expandoObject"); } if (propertyName == null) { throw new ArgumentNullException("propertyName"); } ((IDictionary)expandoObject).Remove(propertyName); } // // 摘要: // 判断 ExpandoObject 是否为空 // // 参数: // expandoObject: public static bool Empty(this ExpandoObject expandoObject) { return !expandoObject.Any(); } // // 摘要: // 判断 ExpandoObject 是否拥有某属性 // // 参数: // expandoObject: // // propertyName: public static bool HasProperty(this ExpandoObject expandoObject, string propertyName) { if (expandoObject == null) { throw new ArgumentNullException("expandoObject"); } if (propertyName == null) { throw new ArgumentNullException("propertyName"); } return ((IDictionary)expandoObject).ContainsKey(propertyName); } // // 摘要: // 实现 ExpandoObject 浅拷贝 // // 参数: // expandoObject: public static ExpandoObject ShallowCopy(this ExpandoObject expandoObject) { return Copy(expandoObject, deep: false); } // // 摘要: // 实现 ExpandoObject 深度拷贝 // // 参数: // expandoObject: public static ExpandoObject DeepCopy(this ExpandoObject expandoObject) { return Copy(expandoObject, deep: true); } // // 摘要: // 拷贝 ExpandoObject 对象 // // 参数: // original: // // deep: private static ExpandoObject Copy(ExpandoObject original, bool deep) { ExpandoObject expandoObject = new ExpandoObject(); IDictionary dictionary = expandoObject; foreach (KeyValuePair item in (IEnumerable>)original) { dictionary.Add(item.Key, (deep && item.Value is ExpandoObject expandoObject2) ? expandoObject2.DeepCopy() : item.Value); } return expandoObject; } } public sealed class ClayArrayEnumerator : IEnumerator { // // 摘要: // 粘土对象 public dynamic _clay; // // 摘要: // 当前索引 private int position = -1; // // 摘要: // 当前元素 public dynamic Current { get { try { return _clay[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } // // 摘要: // 当前元素(内部) object IEnumerator.Current => Current; // // 摘要: // 构造函数 // // 参数: // clay: // 粘土对象 public ClayArrayEnumerator(dynamic clay) { _clay = clay; } // // 摘要: // 推进(获取)下一个元素 public bool MoveNext() { position++; return position < _clay.Length; } // // 摘要: // 将元素索引恢复初始值 public void Reset() { position = -1; } } public sealed class ClayObjectEnumerator : IEnumerator { // // 摘要: // 粘土对象 public dynamic _clay; // // 摘要: // 当前索引 private int position = -1; // // 摘要: // 当前元素 public KeyValuePair Current { get { try { XElement xElement = ((XElement)_clay.XmlElement).Elements().ElementAtOrDefault(position); string text = ((xElement.Name == "{item}item") ? xElement.Attribute("item").Value : xElement.Name.LocalName); return new KeyValuePair(text, _clay[text]); } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } // // 摘要: // 当前元素(内部) object IEnumerator.Current => (KeyValuePair)Current; // // 摘要: // 构造函数 // // 参数: // clay: // 粘土对象 public ClayObjectEnumerator(dynamic clay) { _clay = clay; } // // 摘要: // 推进(获取)下一个元素 public bool MoveNext() { position++; return position < _clay.Length; } // // 摘要: // 将元素索引恢复初始值 public void Reset() { position = -1; } }