.Net Framework 与 .Net Core中的静态构造函数

起因

前几天在看书的时候看到一条内容 > 由于CLR保证一个类型构造器在每个AppDomain中只执行一次,而且(这种执行)是线程安全的,所以非常适合在类型构造器中初始化类型需要的任何单实例(Singleton)对象。
忽然想到,平时自己使用过程中都是通过Lazy来延迟化构建单例对象,就产生了一个疑问,使用Lazy跟直接使用静态构造函数有什么区别,有什么优缺点呢?

经过

抱着这个疑问,我查了一下相关的内容,发现一个很有意思的东西。
关于静态字段的初始化有两种写法

internal sealed class SomeType
{
????private static Int32 s_x = 5;
}
internal sealed class SomeType
{
????private static Int32 s_x;

????static SomeType()
????{
??????? s_x = 5;
????}
}

我在网上所查到的内容是,在使用第一种方法初始化字段的时候,需要添加一个为空的静态构造函数,这样能够保证,该类型是在被用到的时候才去初始化该静态字段。否则,该类型的字段初始化会被提前,甚至可能由于这个不可控的提前导致一些奇怪的问题。但是这种写法也有一个问题,那就是别人可能认为这个空的静态构造函数是无用的而删除这一部分。所以本人认为,下面这种写法更好一些(前提是.Net Framework)。

然后再来研究一下为什么会有这种奇怪的表现。这两种写法看起来没有什么区别,甚至于用JustDecomplie反编译dll出来的代码都是一致的。但是观察生成的IL就会发现他们的区别,第一种写法生成的类会存在beforefieldinit标志。由于编译器并不会提供默认的静态构造函数,所以在没有静态的时候,这个标志会将字段的初始化提前,而这种提前是不可控的。当手动写了静态构造函数,无论构造函数内是否有内容,这个标志都会被去掉,从而促使字段的初始化只有在真正第一次使用到该类的时候才会执行。

自己的尝试

看到这些东西之后,我也自己去做了一些尝试,发现自己的测试项目跑起来并没有这些问题,甚至于字段的初始化还有延迟加载的特性,只有真正用到了这个字段的时候才去初始化这个字段。

思来想去想了很久,突然发现自己的这个项目是一个.Net Core项目,难道说是.Net Core 与.Net Framework在这点的处理上有所不同?随后又去建了一个.Net Framework的项目,发现确实是存在提前初始化的情况。

两者存在不同这件事是可以确定的了,但是具体到底是怎么个不同呢?.Net Core 到底是如何处理beforefieldinit这个标志的呢?

我随后又查了一些相关的内容加上自己做的一些测试,最后得出结论如下:

  • 在存在静态构造函数的情况下,两者并没有什么区别,表现是一致的。
  • 在不存在静态构造函数的情况下,也就是类存在beforefieldinit标签的情况下
    • .Net Framework 会将字段的初始化提前,并且不可控
    • 而.Net Core 会做到延迟加载,只有当某一个字段真正被用到的时候,才会去初始化所有字段。所以在.Net Core中,是不是上面的第一种写法更好?毕竟有延迟加载的效果(虽然一个用到就会导致所有字段都初始化),当然关键还要看是否需要对字段初始化的时间精确控制,如果不需要精确控制,其实哪种写法都没差,这个视具体情况而定。

但是,我觉得既然需要延迟加载,用Lazy来控制每个字段的延迟看起来可控性更高一些。

后记

第一次写博客,有写的不对的地方还请见谅 (*^_^*)

原文地址:https://www.cnblogs.com/LoveLan1314/p/12099476.html

时间: 2024-08-29 12:27:22

.Net Framework 与 .Net Core中的静态构造函数的相关文章

Dotnet Core 在ASP.NET Core中使用静态文件

来自微软官网  在ASP.NET Core中使用静态文件:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/static-files: 提供静态文件 静态文件通常位于web root(<content-root> / wwwroot)文件夹中.有关详细信息,请参阅内容根和Web根.您通常将内容根设置为当前目录,以便web root在开发过程中找到项目. public static void Main(string[] args)

Asp.Net Core 中的静态文件

Asp.Net Core 中的静态文件 在这节中我们将讨论如何使 ASP.NET Core 应用程序,支持静态文件,如 HTML,图像,CSS 和 JavaScript 文件. 静态文件 默认情况下,Asp.Net Core 应用程序不会提供静态文件. 静态文件的默认目录是wwwroot,此目录必须位于项目文件夹的根目录中. 将图片复制并粘贴到 wwwroot 文件夹中.我们假设文件的名称是 banner.jpg.为了能够从浏览器访问此文件,路径为:http://{{serverName}}/b

asp.net core 系列之静态文件

这篇讲解asp.net core中的静态文件(大致翻译于官网). 静态文件,例如HTML,CSS, images和JavaScript. 要想直接被客户端访问,需要做一些配置. 一.Serve static files(提供静态文件服务) 静态文件存储在项目的web root 目录下.默认的目录是<content_root>/wwwroot,但可以通过UseWebRoot方法来改变默认目录. 更多可以查看: See Content root and Web root for more info

C# 静态构造函数使用

当我们想初始化一些静态变量的时候,就需要用到静态构造函数了.这个静态构造函数属于类,而不属于实例,就是说这个构造函数只会被执行一次,即:在创建第一个实例或引用任何静态成员之前,由.NET自动调用. 现在碰到这样一个场景:提供一个静态方法,这个静态方法在不同的地方使用,涉及到一个参数值不同,而其他内容都完全一致.如果是将静态方法的内容复制出来做成另外一个方法,代码冗余太多,做法不可取.使用静态构造函数处理静态变量,则可以尽最大程度简化代码.如下示例: /// <summary> /// 基类 /

如何在ASP.NET Core中应用Entity Framework

注:本文提到的代码示例下载地址> How to using Entity Framework DB first in ASP.NET Core 如何在ASP.NET Core中应用Entity Framework 首先为大家提醒一点,.NET Core和经典.NET Framework的Library是不通用的,包括Entity Framework! 哪怎么办? 别急,微软为.NET Core发布了.NET Core版本的Entity Framework,具体配置方法与经典.NET Framew

在iOS中创建静态库

如果你作为iOS开发者已经有一段时间,可能会有一套属于自己的类和工具函数,它们在你的大多数项目中被重用. 重用代码的最简单方法是简单的 拷贝/粘贴 源文件.然而,这种方法很快就会成为维护时的噩梦.因为每个app都有自己的一份代码副本,你很难在修复bug或者升级时保证所有副本的同步. 这就是静态库要拯救你的.一个静态库是若干个类,函数,定义和资源的包装,你可以将其打包并很容易的在项目之间共享. 在本教程中,你将用两种方法亲手创建你自己的通用静态库. 为了获得最佳效果,你应该熟悉Objective-

ASP.NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介

概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要介绍了ASP.NET Core中StaticFile.Middleware.CustomizeMiddleware和Asp.NetCore Identity.但是由于所有的ASP.NET Core的版本有些老,所以,此次重写一次.使用最新的ASP.NET Core 1.1版本.对于ASP.NET Core 1.1 Preview 1会在以后的文章中介绍 目录 使用静态文件 使用路由

在.NET Core中使用MEF

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:微软的可托管扩展框架也移植到.NET Core上了. 可托管扩展框架(Managed Extensibility Framework,MEF)是微软为大型应用程序(比如Visual Studio这样的东西)提供的一个功能扩展框架,通过一个混合层提升了灵活性.维护性和可测试性.MEF既可以用于第三方插件支持扩展功能(我曾经开发的eBalance就是使用MEF实现插件功能),也能为常见的应用程序带

Andrdoid中实现静态的默认安装和卸载应用

最近好长时间都没有写blog了,主要是因为最近工作上的事以及下载Android源码的事耽误的(下载源码这件事会在后续的blog中写道,这个真的很有意义呀~~),那么今天来写点什么呢?主要的灵感来自于早上看新闻看到一篇文章说有一款应用在后台中卸载用户手机中的所有浏览器的app,不会被用户察觉,但是最后百度浏览器还是用反侦察技术找到这个邪恶的应用然后将其告上法庭了.那么我们就来看看怎么能够实现应用的静态安装和卸载呢?就是不让用户知道,下面就来一步一步的介绍一下实现步骤: 一.访问隐藏的API方式进行