protected virtual CodeNode ReadField(string fieldName) { var field = GetType().GetField(fieldName); var fieldType = field.FieldType; if (fieldType.IsArray) { var elementType = fieldType.GetElementType(); if (elementType.IsValueType) { int len; if (field.TryGetAttribute(out ExpectedAttribute e)) { if (e.Value is string s) { len = s.Length; } else { len = ((Array)e.Value).Length; } } else { len = GetCount(fieldName); } var san = typeof(StructArrayNode <>).MakeGenericType(elementType); var o = (CodeNode)Activator.CreateInstance(san, len); o.Bytes = Bytes; o.Read(); var value = san.GetField("arr").GetValue(o); field.SetValue(this, value); o.NodeValue = value.GetString(); return(o); } throw new InvalidOperationException($"{GetType().FullName}. {field.Name} is an array {elementType}[]"); } if (fieldType.IsClass) { var o = (CodeNode)(field.GetValue(this) ?? (CodeNode)Activator.CreateInstance(fieldType)); o.Bytes = Bytes; o.Read(); field.SetValue(this, o); return(o); } Type sn; if (fieldType.IsEnum) { sn = typeof(EnumNode <>).MakeGenericType(fieldType);; } else if (fieldType.IsValueType) { sn = typeof(StructNode <>).MakeGenericType(fieldType); } else { throw new InvalidOperationException(fieldType.Name); } { CodeNode o = (CodeNode)Activator.CreateInstance(sn); o.Bytes = Bytes; o.Read(); var value = sn.GetField("t").GetValue(o); field.SetValue(this, value); o.NodeValue = value.GetString(); return(o); } }