公司网站平台,现在做电商哪个平台好,网站建设怎么分类,网站demo制作工具前言最近在公众号上看到一篇文章《究竟是什么可以比反射还快实现动态调用#xff1f;》#xff0c;它使用的是Newbe.ObjectVisitor#xff0c;基于C#表达式树访问一个普通class的所有属性和对应的值#xff0c;可以拥有比直接使用反射快上10倍的性能。就这一需求来说#… 前言最近在公众号上看到一篇文章《究竟是什么可以比反射还快实现动态调用》它使用的是Newbe.ObjectVisitor基于C#表达式树访问一个普通class的所有属性和对应的值可以拥有比直接使用反射快上10倍的性能。就这一需求来说我认为Source Generators应该会更快因为访问代码在编译时而不是运行时就生成了。事实也验证了确实如此实现这次我们使用第三方开发的Source Generators类库来实现。1.引用Nuget包创建示例控制台程序引用如下Nuget包AOPMethodsCommon
AOPMethodsGenerator2.设置Attribute在需要动态调用的类上声明Attribute[AutoMethods(template TemplateMethod.CustomTemplateFile, CustomTemplateFileName template.txt)]
public class Yueluo3.代码模板添加template.txt用在Source Generators生成动态调用代码的模板.内容如下using System;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using System.Runtime.CompilerServices;
namespace {{NamespaceName}} {public static class {{ClassName}}Extentions{public static string ValueStringProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType string ) ~}}if(string.Compare({{mi.Name}},val,StringComparison.CurrentCultureIgnoreCase)0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException(cannot find val);}public static int ValueIntProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType int ) ~}}if(string.Compare({{mi.Name}},val,StringComparison.CurrentCultureIgnoreCase)0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException(cannot find val);}public static object ValueProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}if(string.Compare({{mi.Name}},val,StringComparison.CurrentCultureIgnoreCase)0) {return obj.{{mi.Name}};}{{~ end ~}}throw new ArgumentException(cannot find val);}}
}模板使用了scriban进行解析具体语法详见https://github.com/scriban/scriban/blob/master/doc/language.md以ValueStringProperty方法举例来说public static string ValueStringProperty(this {{ClassName}} obj, string val){{{~ for mi in Properties ~}}{{~ if( mi.ReturnType string ) ~}}if(string.Compare({{mi.Name}},val,StringComparison.CurrentCultureIgnoreCase)0) {return obj.{{mi.Name}};}{{~ end ~}}{{~ end ~}}throw new ArgumentException(cannot find val);
}遍历类的所有属性Properties判断当前属性返回类型mi.ReturnType是string则返回对应属性名的值。4.使用下面是Benchmark测试代码分别使用了Newbe.ObjectVisitor和Source Generators[Benchmark]
public string GetterString() ValueGetterYueluo, string, string.GetGetter(_nameProperty).Invoke(_yueluo);[Benchmark]
public int GetterInt() ValueGetterYueluo, int, int.GetGetter(_ageProperty).Invoke(_yueluo);[Benchmark]
public string GetterString2()
{ return _yueluo.ValueStringProperty(Name);
}[Benchmark]
public int GetterInt2()
{return _yueluo.ValueIntProperty(Age);
}可以看到Source Generators生成的代码可读性更高。结论对于编译时可生成的功能尽量使用Source Generators实现可以达到更好的性能和可读性。如果你觉得这篇文章对你有所启发请关注我的个人公众号”My IO“