seo网站文章编辑软件,营销网站开发公司,flash 网站开发教程,网站制作公司在哪里找前言在开发中#xff0c;我们经常需要创建某个类型实例的副本。常用的方式#xff0c;是继承ICloneable接口#xff0c;然后自行实现Clone()#xff0c;这会耗费一定的开发时间#xff1b;或者使用序列化/反序列化方式变相实现#xff0c;但是性能不高。现在#xff0c;… 前言在开发中我们经常需要创建某个类型实例的副本。常用的方式是继承ICloneable接口然后自行实现Clone()这会耗费一定的开发时间或者使用序列化/反序列化方式变相实现但是性能不高。现在可以尝试用Source Generators实现。实现思路首先需要Clone的类必须声明一个特定的CloneableAttribute这样Source Generators才知道为谁实现Clone方法。然后Source Generators遍历该类型的所有属性为其编写属性赋值代码。如果属性本身也是Cloneable类型那就调用属性对应类型的Clone方法实现深度克隆。具体代码1.添加CloneableAttribute向待编译项目加入CloneableAttribute代码const string cloneableAttributeText using System;namespace CloneableDemo
{public sealed class CloneableAttribute : Attribute{public CloneableAttribute(){}}
}
;context.AddSource(CloneableAttribute, SourceText.From(cloneableAttributeText, Encoding.UTF8));2.遍历CloneableAttribute声明类找到声明了CloneableAttribute的所有类型var cloneableAttribute compilation.GetTypeByMetadataName(CloneableDemo.CloneableAttribute);
foreach (var classSymbol in classSymbols)
{if (!classSymbol.TryGetAttribute(cloneableAttribute, out var attributes))continue;context.AddSource(${classSymbol.Name}_clone.cs, SourceText.From(CreateCloneCode(classSymbol), Encoding.UTF8));
}3.生成Clone代码遍历属性生成Clone方法private string CreateCloneableCode(INamedTypeSymbol classSymbol){string namespaceName classSymbol.ContainingNamespace.ToDisplayString();var propertyNames classSymbol.GetMembers().OfTypeIPropertySymbol();var codes new StringBuilder();foreach (var propertyName in propertyNames){if (isCloneable(propertyName)){codes.AppendLine($ {propertyName} obj.{propertyName}?.Clone(),);}else{codes.AppendLine($ {propertyName} obj.{propertyName},);}}return $using System.Collections.Generic;namespace {namespaceName}
{{public static class {classSymbol.Name}Extentions{{public static {classSymbol.Name} Clone(this {classSymbol.Name} obj){{return new {classSymbol.Name}{{{codes.ToString()}}};}}}}
}};}4.使用现在就可以在目标项目中使用Clone方法了:[Cloneable]
public class Class1
{public string A { get; set; }public Class2 B { get; set; }
}[Cloneable]
public class Class2
{public string A { get; set; }
}var obj new Class2()
{A My IO,
};
var deep new Class1()
{A My IO,B obj
};
var clone deep.Clone();结论有了Source Generators可以让编译器帮我们自动实现Clone方法既节约了开发时间又保证了性能如果你觉得这篇文章对你有所启发请关注我的个人公众号”My IO“