






















使用方法,
string code = InitializerCodeGenerator.GenerateInitializer(this);
例如:
public class ParaParseConfig
{
public string ParaNo { get; set; }
public JsonDataType ParaType { get; set; }
public List<ParaParseConfig> Sub { get; set; }
public string GetCode()
{
string code = InitializerCodeGenerator.GenerateInitializer(this);
return code;
}
}
完整代码
public static class InitializerCodeGenerator
{
public static string GenerateInitializer(object obj)
{
if (obj == null) return "null";
var sb = new StringBuilder();
BuildExpression(obj, sb, 0, new HashSet<object>(ReferenceEqualityComparer.Instance));
return sb.ToString().TrimEnd('\r', '\n');
}
private static void BuildExpression(object obj, StringBuilder sb, int indent, HashSet<object> visited)
{
if (obj == null)
{
sb.Append("null");
return;
}
if (visited.Contains(obj))
{
sb.Append("/* circular reference */");
return;
}
Type type = obj.GetType();
// 基本类型 / 字符串 / 枚举 / 可空类型 → 直接输出字面量
if (IsSimpleType(type))
{
sb.Append(GetLiteral(obj));
return;
}
// 可空类型(已经包含在 IsSimpleType 中,但单独处理也可)
Type underlying = Nullable.GetUnderlyingType(type);
if (underlying != null)
{
sb.Append(GetLiteral(obj));
return;
}
visited.Add(obj);
// 数组
if (type.IsArray)
{
var arr = (Array)obj;
Type elemType = type.GetElementType();
sb.Append($"new {GetTypeName(elemType)}[{arr.Length}]{{");
for (int i = 0; i < arr.Length; i++)
{
if (i > 0) sb.Append(", ");
BuildExpression(arr.GetValue(i), sb, indent + 1, visited);
}
sb.Append("}");
return;
}
// 泛型集合
if (typeof(IEnumerable).IsAssignableFrom(type) && type.IsGenericType)
{
var enumerable = (IEnumerable)obj;
var genericArgs = type.GetGenericArguments();
// 字典
if (type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>)))
{
var dict = (IDictionary)obj;
sb.Append($"new {GetTypeName(type)}(){{");
bool first = true;
foreach (DictionaryEntry entry in dict)
{
if (!first) sb.Append(", ");
first = false;
sb.Append("{ ");
BuildExpression(entry.Key, sb, indent + 1, visited);
sb.Append(", ");
BuildExpression(entry.Value, sb, indent + 1, visited);
sb.Append(" }");
}
sb.Append("}");
}
else // List, HashSet, Queue, Stack ...
{
sb.Append($"new {GetTypeName(type)}(){{");
bool first = true;
foreach (var item in enumerable)
{
if (!first) sb.Append(", ");
first = false;
BuildExpression(item, sb, indent + 1, visited);
}
sb.Append("}");
}
return;
}
// 普通类 / 结构体 → 对象初始化器
sb.AppendLine($"new {GetTypeName(type)}()");
sb.AppendLine(new string(' ', indent * 4) + "{");
// 公共可写属性(不含索引器)
foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanWrite && p.GetIndexParameters().Length == 0))
{
object value = prop.GetValue(obj);
if (value == null) continue;
sb.Append(new string(' ', (indent + 1) * 4));
sb.Append($"{prop.Name} = ");
BuildExpression(value, sb, indent + 1, visited);
sb.AppendLine(",");
}
// 公共字段
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Instance))
{
object value = field.GetValue(obj);
if (value == null) continue;
sb.Append(new string(' ', (indent + 1) * 4));
sb.Append($"{field.Name} = ");
BuildExpression(value, sb, indent + 1, visited);
sb.AppendLine(",");
}
sb.Append(new string(' ', indent * 4) + "}");
}
private static bool IsSimpleType(Type t)
{
if (t.IsPrimitive || t == typeof(string) || t.IsEnum || t == typeof(decimal) ||
t == typeof(DateTime) || t == typeof(Guid) || t == typeof(TimeSpan) ||
t == typeof(Uri) || t == typeof(Version))
return true;
Type underlying = Nullable.GetUnderlyingType(t);
return underlying != null && IsSimpleType(underlying);
}
private static string GetLiteral(object value)
{
if (value == null) return "null";
Type t = value.GetType();
if (t == typeof(string)) return $"\"{EscapeString((string)value)}\"";
if (t == typeof(char)) return $"'{value}'";
if (t == typeof(bool)) return (bool)value ? "true" : "false";
if (t.IsEnum) return $"{t.FullName}.{value}";
if (t == typeof(decimal)) return $"{value}m";
if (t == typeof(float)) return $"{value}f";
if (t == typeof(double)) return $"{value}d";
if (t == typeof(long)) return $"{value}L";
if (t == typeof(uint)) return $"{value}u";
if (t == typeof(ulong)) return $"{value}UL";
if (t == typeof(DateTime)) return $"new DateTime({((DateTime)value).Ticks}L)";
if (t == typeof(Guid)) return $"new Guid(\"{value}\")";
if (t == typeof(TimeSpan)) return $"new TimeSpan({((TimeSpan)value).Ticks}L)";
if (t == typeof(Uri)) return $"new Uri(\"{value}\")";
if (t == typeof(Version)) return $"new Version(\"{value}\")";
if (Nullable.GetUnderlyingType(t) != null)
{
var nullable = value as dynamic;
return nullable.HasValue ? GetLiteral(nullable.Value) : "null";
}
return value.ToString(); // fallback
}
private static string EscapeString(string s)
{
return s.Replace("\\", "\\\\")
.Replace("\"", "\\\"")
.Replace("\n", "\\n")
.Replace("\r", "\\r")
.Replace("\t", "\\t");
}
private static string GetTypeName(Type type)
{
if (!type.IsGenericType) return type.FullName ?? type.Name;
var sb = new StringBuilder();
sb.Append(type.GetGenericTypeDefinition().FullName?.Split('`')[0]);
sb.Append("<");
var args = type.GetGenericArguments();
for (int i = 0; i < args.Length; i++)
{
if (i > 0) sb.Append(", ");
sb.Append(GetTypeName(args[i]));
}
sb.Append(">");
return sb.ToString();
}
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。