.NET Core 特性(Attribute)底层原理解析
Attribute的使用场景
Attribute不仅仅局限于C#中,在整个.NET框架中都提供了非常大的拓展点,任何地方都有Attribute的影子
- 编译器层
比如 Obsolete,Conditional - C#层
GET,POST,Max,Range,Require - CLR VM层
StructLayout,DllImport - JIT 层
MethodImpl
Attribute在C#中的调用
举个常用的例子,读取枚举上的自定义特性。
public enum Test { [EnumDescription("hhhhhh")] None = 0, [EnumDescription("xxxxxx")] Done =1 } private static IEnumerableGetEnumDescriptions(this Enum e) { IEnumerable result = null; var type = e.GetType(); var fieldInfo = type.GetField(e.ToString()); var attr = fieldInfo?.GetCustomAttributes(typeof(EnumDescriptionAttribute), false); if (attr?.Length > 0) { result = attr.Cast ().Select(x => x.Description); } return result ?? Enumerable.Empty (); }
可以看到,Attribute底层在C#中实现依旧是依赖反射,所以为什么说Attribute是写给代码看的注释,因此对反射的优化思路也可以用在Attribute中。
比如在代码中,使用Dictionary缓存结果集。避免过多调用反射造成的性能问题。
private static IEnumerableGetEnumDescriptionsCache(this Enum e) { var key = $"{e.GetType().Name}_{e.ToString()}"; if (_enumMap.ContainsKey(key)) { return _enumMap[key]; } else { var result = GetEnumDescriptions(e); _enumMap.TryAdd(key, result); return result; } }
循环100000次造成的性能差距还是很明显的
Newtonsoft.Json对Attrubute的使用
以JsonConverter为蓝本举例说明。
public class Person { [JsonConverter(typeof(DateTimeConverter))] public DateTime CreateTime { get; set; } } public class DateTimeConverter : JsonConverter{ public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.Value == null) return DateTime.MinValue; if (DateTime.TryParse(reader.Value.ToString(), out DateTime result)) return result; return DateTime.MinValue; } public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer) { writer.WriteValue(value.ToString("yyyy-MM-dd HH:mm:ss")); } }
定义了一个Attribute:JsonConverter.其底层调用如下:
[RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)] [RequiresDynamicCode(MiscellaneousUtils.AotWarning)] public static JsonConverter? GetJsonConverter(object attributeProvider) { // 底层还是调用Reflection,为了性能,也缓存了对象元数据。 JsonConverterAttribute? converterAttribute = GetCachedAttribute(attributeProvider); if (converterAttribute != null) { Func
https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
Attribute在CLR上的调用
public class NativeMethods { [DllImport("xxxxx", EntryPoint = "add", CallingConvention = CallingConvention.Cdecl)] public extern static int ManagedAdd(int a, int b); }
在CLR中,同样用来调用 C/C++ 的导出函数。有兴趣的朋友可以使用windbg查看线程调用栈。以及在MetaData中有一张ImplMap表,存储着C#方法与C++函数的mapping关系
Attribute在JIT上的调用
public class Person { public int id { get; set; } = 0; [MethodImpl(MethodImplOptions.Synchronized)] public void SyncMethod() { id++; } }
JIT会自动为该Attribute注入同步代码
其本质就是注入lock同步块代码,只是颗粒度在整个方法上。相对比较大
结论
Attrubute在C#层面,底层使用反射。因此使用自定义Attribute时,酌情使用缓存来提高性能
到此这篇关于.NET Core 特性(Attribute)底层原理浅谈的文章就介绍到这了,更多相关.NET Core 底层原理内容请搜索科站长以前的文章或继续浏览下面的相关文章希望大家以后多多支持科站长!
上一篇:.NET 8 强大功能 IHostedService 与 BackgroundService 实战教程
栏 目:ASP.NET
本文标题:.NET Core 特性(Attribute)底层原理解析
本文地址:https://www.fushidao.cc/wangluobiancheng/3287.html
您可能感兴趣的文章
- 03-31详解如何在.NET代码中使用本地部署的Deepseek语言模型
- 02-06.net core如何使用Nacos注册中心
- 01-28使用.NET8构建一个高效的时间日期帮助类
- 01-26.NET Core GC压缩(compact_phase)底层原理解析
- 01-24在ASP.NET中读写TXT文本文件的多种方法
- 01-24在ASP.NET中读写XML数据的多种方法
- 01-24.NET轻松实现Excel转PDF的三种方法详解
- 01-23.NET9 AOT部署方案详解
- 01-23.NET NativeAOT 用法指南
- 01-23iis部署前后端分离项目全过程(Vuet前端和.NET6后端)


阅读排行
推荐教程
- 03-31详解如何在.NET代码中使用本地部署的Deepseek语言模型
- 11-23移动互联网广告有哪些模式?
- 11-22.net 应对网站访问压力的方案总结
- 11-22详解ASP.NET提取多层嵌套json数据的方法
- 11-23网站投放广告如何达到最好的效果
- 11-22.net 应对网站访问压力的方案总结
- 11-23网站打开速度慢解决办法
- 11-23草根站长为什么喜欢做门户站
- 11-22ASP.NET MVC分页问题解决
- 11-22ASP.NET编程简单实现生成静态页面的方法