实例构造器,值类型构造器和类型构造器

手把手调试:如何为高通Hypervisor上的GuestOS添加一个自定义的HAB服务通道 本文详细介绍了如何在高通Hypervisor环境下为GuestOS添加自定义HAB服务通道的全过程。从HAB通信框架的核心概念解析到设备树节点的动态注入机制,再到物理通道的内核层实现和用户层测试,提供了完整的开发案例和调试技巧,帮助开发者高效构建定制化通信服务。 阅读详情

 

(学习手册自:框架设计 CLR Via C#)

8.1实例构造器和类:P175

 

实例构造器不能被继承,也就是说类只能拥有自己定义的实例构造器,许多编辑器定义一个默认的无参构造器,它的实现只是调用基类的无参构造函数

如下例:

public class SomeType{}相当于public class SomeType{  public SomeType():base(){}   }

如果类的修饰符为abstract,那么编译器生成的默认构造器将为protected,否则为public

如果类的修饰符为static,那么编译器根本不会在类的构造器中生成一个默认的构造器

如非必要我们可以不向一个类提供构造函数,编译器会在后台创建一个默认的构造函数。但如果提供了自定义的构造函数,编译器就不会提供默认的构造函数。

例:http://www.cnblogs.com/xiongpq/archive/2010/08/18/1801965.html

自己写的例子:

class Test

    {

        static void Main(string[] args)

        {

            Test2 tests = new Test2(1, 2);

            Console.WriteLine("OK");

            Console.ReadKey();

        }

    }

    class Test1

    {

        public Test1(int a, int b)

        {

            Console.Write("aa" + (a + b));

        }

    }

    class Test2 : Test1

    {

        public Test2(int a, int b): base(a, b)//如果不写将默认为base(),此时如果基类中不存在无参构造函数,将会报错,因为基类如果提供了自定义的构造函数,编译器就不会提供默认的无参构造函数了

        {

 

            Console.Write(a + b);

        }

}

 

如果一个类中存在多个构造器和实例字段,应考虑在定义实例字段的时候避免同时对他们进行初始化(内联初始化),如果给他们初始化的同时,在构造器中又再次对他们进行赋值,会出现代码膨胀现象,如此例:

 

    class SomeType

    {

        //不要显式初始化下面的字段

        private Int32 m_x=1;

        private String m_s="2";

        private Double m_d=3.0;

        private Byte m_b=1;

 

        //该构造器将所有的字段都设为默认值。所有其他构造器都必须显式调用这个构造器

        public SomeType()

        {

 

            m_x = 5;

            m_s = "Hi there";

            m_d = 3.14159;

            m_b = 0xff;

        }

 

        //该构造器首先将所有的字段都设为默认值,然后修改m_x

        public SomeType(Int32 x)

            : this()

        {

            m_x = x;

        }

 

        //该构造器首先将所有的字段都设为默认值,然后修改m_s

        public SomeType(String s)

            : this()

        {

            m_s = s;

        }

 

        //该构造器首先将所有的字段都设为默认值,然后修改m_x和m_s

        public SomeType(Int32 x, String s)

            : this()

        {

            m_x = x;

            m_s = s;

        }

        static void Main(string[] args)

        {

           

        }

}

此时它的无参构造函数中生成的IL代码为(代码膨胀94):

当不给上述的实例字段进行初始化时,生成的IL代码如下(54):

 

 

 

8.2值类型构造器:P179

1.公共语言运行库允许创建值类型的实例,无法阻止其初始化,编译器不会为值类型生成无参构造函数,C#不允许值类型生成无参构造函数

2.CLR允许值类型定义有参构造器,但是执行值类型上定义的构造器的唯一方法是编写代码显示的调用这些构造器

3.虽然C#不允许值类型拥有无参构造器,但是CLR允许值类型拥有无参构造器(C#不能在值类型中内联实例字段的初始化)

internal struct SomeValueType { private Int32 x= 5;//不能在值类型中内联实例字段的初始化 }

4.可验证代码要求值类型的每个字段都要在值类型的任何字段被读取之前进行初始化,所

以值类型的构造器必须初始化值类型的所有字段。

 

8.3类型构造器(静态构造器):P180

1.类型构造器是用来设置类型的初始状态,默认情况下不在类型内部定义类型构造器

2.类型构造器只能有一个且永远没有参数,当类第一次被访问时执行

3.类型构造器不允许出现访问修饰符,且默认为私有的

4.C#允许在值类型中定义无参类型构造器,但永远也不要定义,因为CLR中存在不调用

值类型类型构造器的情况,如下例:

5.C#允许值类型使用内联初始化语法初始化静态字段

如 struct/class SomeType{ private static Int32 x=5; }

相当于:

Struct/Class SomeType{  private static Int32 x;   static SomeType(){x=5;}  }

注意:类型构造器不调用基类型的类型构造器

 

类型构造器的性能(P183):

8.3节中我们提到对类型构造器的调用是一件棘手的事情,并且说明了一些棘手之处:JIT编译器必须决定是否生成调用类型构造器的代码;CLR要确保对类型构造器的调用是线程安全的。事实证明,这只是一个开头,与类型构造器性能相关的棘手事情还有很多

 

JIT编译器需要决定它是否必须生成一个调用来执行方法中的类型构造器。如果JIT编译器决定生成该调用,那么,JIT编译器必须决定在什么地方生成调用,有以下两种情况:

A. JIT编译器可以在首次创建类型实例的代码之前或者在访问类的非继承字段或成员的代码之前立即生成调用。因为CLR会在确定的时刻调用类型构造器,所以这种情况被称为精确语义(precise semantic)。

B. JIT编译器有时可以在访问非继承静态字段的代码前生成调用。因为CLR确保只有静态构造器可以在静态字段被访问之前的某个时候运行(静态构造器可能会很早运行),所以这种情况称为字段初始化前语义(before-field-init semantic)。

通俗的解释:

类型构造器只调用一次,JIT编译器需要在适当的时候确定生成调用类型构造器的代码,有以上两种地方可以生成。字段初始化前语义(隐式构造器)会在生成的类的类型定义条目表中标记一个BeforeFieldInit元数据标记,精确语义(显示构造器)不会

例:

internal sealed class BeforeField

    {

        public static Int32 s_x = 123;

    }

 

    //因为这个类确实显式定义了类型构造器,所以C#在元数据中没有用BeforeFieldInit标识来标记

    //类型定义

    internal sealed class Precise1

    {

        public static Int32 s_x;

        static Precise1() { s_x = 123; }

    }

 

    public sealed class Program

{

   static  Program(){}

        public static void Main()

        {

            const Int32 iterations = 1000 * 1000 * 1000;

            PerfTest1(iterations);

            PerfTest2(iterations);

        }

 

        //当这个方法被JIT编译时,BeforeField和Precise1类的类型构造器还没有被执行,因此,

        //这些构造器的调用将内嵌在该方法的代码中,从而使运行速度变慢

        private static void PerfTest1(Int32 iterations)

        {

            Stopwatch sw = Stopwatch.StartNew();

            for (Int32 x = 0; x < iterations; x++)

            {

                //JIT编译器将下述代码提前执行以调用BeforeField的类型构造器,以便它在循

                //环开始前执行

                BeforeField.s_x = 1;

            }

            Console.WriteLine("PerfTest1: {0} BeforeField", sw.Elapsed);

 

            sw = Stopwatch.StartNew();

            for (Int32 x = 0; x < iterations; x++)

            {

                //JIT编译器在这里生成调用Precise1类的类型构造器的代码,以便它检查是否对每一次

                //循环迭代都必须调用构造器

                Precise1.s_x = 1;

            }

            Console.WriteLine("PerfTest1: {0} Precise1", sw.Elapsed);

        }

        //当这个方法被JIT编译时,BeforeField和Precise1类的类型构造器已经被执行,因此,

        //这些构造器的调用没有内嵌在该方法的代码中,从而使运行速度变快

        private static void PerfTest2(Int32 iterations)

        {

            Stopwatch sw = Stopwatch.StartNew();

            for (Int32 x = 0; x < iterations; x++)

            {

                BeforeField.s_x = 1;

            }

            Console.WriteLine("PerfTest2: {0} BeforeField", sw.Elapsed);

 

            sw = Stopwatch.StartNew();

            for (Int32 x = 0; x < iterations; x++)

            {

                Precise1.s_x = 1;

            }

            Console.WriteLine("PerfTest2: {0} Precise1", sw.Elapsed);

        }

}

生成的定义表条目如下图所示:

基于高精度三维机器视觉的新能源汽车锂电池表面缺陷检测 在机器视觉行业迅速发展的背景下,市场上提供了功能强大且种类齐全的3D相机系列,可以满足锂电池从电芯到模组各个工艺和工位的3D检测需求。 阅读详情

相关推荐

机器学习篇-KNN算法实现鸢尾花模型和手写数字识别模型

一个样本最相似的k个样本中的大多数属于某一个类别, 则该样本也属于这个类别类似于: 近朱者赤近墨者黑回归机器建模流程:数据获取数据基本处理(空值和非法值)特征工程(特征提取, 特征预处理(归一化, 标准化), 特征降维, 特征选择, 特征组合)模型训练模型预测模型评估# 1. 定义函数 dm01_load_iris(), 用于加载 鸢尾花数据集, 并简单查看下数据集的各部分.# 1. 加载数据集.​# 2. 打印iris_data, 发现其实是1个: 字典.​。

m0_60916732的博客 2403

类构造器<clinit>(),实例构造器<init>()

clinit>()()和()这两个构造器的产生实际上是一种代码收敛的过程编译器会把1、(对于实例构造器而言是“{}”块,对于类构造器而言是“static{}”块2、(对于实例构造器而言是实例变量,对于类构造器而言是类变量3、仅仅是实例构造器()方法中无须调用父类的()方法,Java虚拟机会自动保证父类构造器的正确执行)等操作收敛到()和()方法之中。并且保证。

张紫娃的博客 1866

GD32F303 Keil 工程项目从零搭建实战指南

本文是一份详细的GD32F303 Keil工程项目从零搭建实战指南。文章阐述了亲手搭建工程的重要性,并逐步指导开发者完成从环境准备、目录规划、工程创建、文件添加、关键配置到编译调试的全过程。重点讲解了如何正确选择启动文件、添加外设库、配置头文件路径和全局宏,旨在帮助开发者深入理解工程结构,掌握GD32F303开发的核心技能,实现从“会用”到“懂”的跨越。

weixin_29190651的博客 404

实例构造器和类型构造器的一些比较

(技术等级:200)实例构造器即实例构造函数,类型构造器也就是静态构造函数.(1)在实例构造器里面,我们可以初始化类的实例字段和静态字段. public class Test{    private int m;    private static int n;    public Test()    {        m=1;//相当于this.m=1;        n=2;//猛的一看...

weixin_34150830的博客 200

Anchor graph 对齐文献解读

Align then Fusion: Generalized Large-scale Multi-view Clustering with Anchor Matching Correspondences文献解读

atease0001的博客 1163

双目视觉入门实战:用Matlab标定相机,再到Python OpenCV完成测距的完整链路

本文详细介绍了双目视觉技术的完整实现流程,从Matlab相机标定到Python OpenCV测距的全链路实践。重点解析了Matlab与OpenCV的参数转换技巧,以及立体校正、视差计算等关键步骤的代码实现,帮助开发者快速掌握双目测距系统的搭建方法。

weixin_29166013的博客 444

类型构造器与实例构造器

比较实例构造器和类型构造器的区别,类型构造器必须是static,并且不允许定义访问修饰符,类型构造器只能被执行一次。: class mybaseclass { public mybaseclass() { Console.WriteLine("基类实例构造器"); } s...

aibixin8234的博客 202

昆仑通态屏幕制作(连载1)---接触篇

写在开始 背景:最近出了做QT、LORA和4G,还做了一个屏幕。以前做了一个迪文的串口屏幕,发现网上的教程很多,所以连载就不更新了,并且迪文屏幕的设置什么的比较简单,应该从网上都能找到对应的教程。而现在用的昆仑通态的屏幕属于嵌入式屏幕,至于为啥叫嵌入式,也不是很明白,反正就是需要用这个屏幕,嵌入式不嵌入式不重要了。重要的是能用,并且能实现串口屏幕不能实现的功能。所以选定昆仑通态的一款屏幕。 文章语言:我比较习惯用比较糙的语言介绍做的东西,有时候不太准备,但是为了方便理解,还请大家谅解。用...

weixin_45426095的博客 6735

类加载顺序,JVM角度分析理解,类构造器方法<clinit>以及实例构造器方法<init>执行顺序

今天先来分析一下经常遇到的一个问题,在笔试面试中可能会经常遇见,类中字段代码块的加载顺序等,从jvm角度分析一下这个问题。我们先来看下知识点,接下来进行代码实践验证。 &lt;clinit&gt;,类构造器方法,在jvm第一次加载class文件时调用,因为是类级别的,所以只加载一次,是编译器自动收集类中所有类变量(static修饰的变量)和静态语句块(static{}),中的语句合并产生的,编译...

youngogo的博客 4142

Frigate进阶玩法:如何用MQTT和Python脚本扩展你的自定义目标检测算法

本文详细介绍了如何通过MQTT和Python脚本扩展Frigate的自定义目标检测算法,无需修改源码即可实现特殊场景(如工业设备异常、农业病虫害识别)的高效检测。文章涵盖Frigate配置、外部检测服务构建、高级集成技巧及性能优化实践,帮助开发者灵活扩展智能监控能力。

weixin_42662293的博客 348

YOLOv13|损失函数优化篇:Focal EIOU 保持良好性能的同时,提供更高效的计算和更稳定的训练过程-包源码

Focal IoU与EIoU:目标检测中的损失函数优化 摘要:本文深入探讨了目标检测中两种重要的边界框回归损失函数优化方法。Focal IoU借鉴Focal Loss思想,通过(1-IoU)^γ因子调节损失权重,使模型更关注难样本(低IoU预测框),有效解决了传统IoU Loss对难易样本权重相同的问题。EIoU则在CIoU基础上改进,通过简化长宽比计算、分离宽高损失项,提升了计算效率和训练稳定性。两种方法分别从样本权重分配和损失函数结构优化角度,显著提升了目标检测性能,为实际应用提供了更高效的解决方案。文

FJN110的博客 1864

实例构造器与值类型和引用类型、类型构造器

构造器名与类名一致。 一。实例构造器 1。实例构造器与类(引用类型) 构造器是允许将类型的实力初始化为良好状态的一种特殊方法。 创建一个引用类型的实例时(类),首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步索引快),最后调用类型的实例构造器来设置对象的初始状态。 new一个类所发生的事:分配内存(托管堆上)——》初始化额外开销(类型对象指针和同步索引快)...

weixin_30802171的博客 116

OpenClaw(Clawdbot/Moltbot)如何正确的配置浏览器,实现对浏览器的自动化操作功能(浏览器状态为running:false怎么办)

OpenClaw(Clawdbot/Moltbot)浏览器自动化功能无效?🤖 本文详细介绍如何解决这个问题🔧,让你的OpenClaw(Clawdbot/Moltbot)真正具备"睁眼看世界"的能力,支持网页搜索、点击操作和截图等功能 ✅

XiaoqiangClub的博客 8105

CLR via C# 方法 实例构造器和结构(值类型)

值类型(struct)构造器的工作方式与引用类型(class)的构造器截然不同。CLR总是允许创建值类型的实例,并且没有办法阻止值类型的实例化。所以,值类型其实并不需要定义构造器,C#编译器根本不会为值类型内联(嵌入)默认的无参构造器。 为了构造一个Rectangle,必须使用new操作符,而且必须指定构造器。在这个例子中,调用的是C#编译器自动生成的默认构造器。为Rectangle分配内存...

songhuanfei2017的博客 313

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

二十:构造器之二:实例构造器和结构(值类型)

值类型不像引用类型那样,必须要有构造器,所以编译器不会为值类型生成无参构造器。如下代码: internalstructPoint { publicInt32x,y; } internalsealedclassRefType { publicPointleft,right; } 为了构建引用类型RefType的实例,必须使用new操作...

weixin_30914981的博客 67

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C# 构造器总结

在C#中,构造器分为实例构造器和类型构造器, 一、实例构造器 构造引用类型的对象时,在调用实例 构造器之前,为对象分配的内存总是归0,没有被构造器显示重写的字段都保证获得0或null的值 在一个类中,如果我们没有显示的定义任何构造器,那么C#编译器将定义一个默认的无参构造器,这个无参构造器会简单的调用一个基类的无参构造器,如下面Some...

weixin_30363981的博客 145

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C#类型构造器

类型构造器也称为静态构造器,类构造器,或类型初始化器 类型构造器可以用于接口(C#不允许这样做),引用类型,值类型。实例构造器用来设置一个类型某个实例的初始化状态,类型构造器用来设置一个类型的初始化状态。默认情况下,类型没有定义类型构造器。下面展示如何定义值类型和引用类型的构造器: internal sealed class SomeRefType { static...

weixin_30608131的博客 83

【CLR via C#】第8章-方法

1.创建引用类型的实例时,首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步块索引),最后调用类型的实例构造器`来设置对象的初始状态。 2.和其他方法不同,实例构造器永远不能被继承。 也就是说,类只有自己定义的实例构造器。因为不能被继承,所以实例构造器不能使用以下修饰符:virtual,new,override,sealed和abstract。 3.如果类的修饰符为abstract,那么编译器生成的默认构造器的可访问性就为protected。 如果类的修饰符为static(seale

背水的博客 314

《CLR via C#》精髓:构造器

构造器包括实例构造器(Instance Constructor)和类型构造器(Type Constructor)。它们针对引用类型和值类型拥有不同的行为和准则。 实例构造器 引用类型 实例构造器用于初始化对象状态; 被调用前,对象所分配的内存总会被清零; 永远不会被继承; 如果没有显式地定义任何构造器,C#编译器会自动生成一个默认(无参)构造器,其实现代码将调用基类的无参构造器; ...

weixin_34278190的博客 127

构造器

引用类型 构造器是将类型的实例初始化为良好状态的特殊方法,创建引用类型的实例时,首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步块索引),最后调用类型的实例构造器来设置对象的初始化状态。 构造引用类型对象时,在电泳类型的实例构造器之前,为对象分配的内存总是先被归0,没有被构造器显示重写的所有字段都保证获得0或null值。 和其他方法不同,实力构造器永远不能被继承,也...

weixin_30765319的博客 74

swift4.0-11 类和结构体

代码学习swift4.0, 类和结构体 // // main.swift // SwiftLearn11-类和结构体 // // Created by iOS on 2018/5/7. // Copyright © 2018年 weiman. All rights reserved. // impor...

weixin_33971205的博客 139

Swift 类和结构体

结构体和类有着相似的定义方式。你通过struct关键字引入结构体,通过class// 在这里定义结构体// 在这里定义类注意每当你定义一个新的结构体或者类时,你都是定义了一个新的 Swift 类型。请使用这种方式来命名类型(如这里的SomeClass和),以便符合标准 Swift 类型的大写命名风格(如StringInt和Bool请使用这种方式来命名属性和方法(如frameRate和),以便和类型名区分。在上面的示例中定义了一个名为Resolution的结构体,用来描述基于像素的分辨率。

xiaoxiaobukuang的专栏 1353

Swift之构造器的使用

1.默认构造器 当结构体或者类的所有属性都有默认值,同时没有自定义的构造器,这个时候,Swift就会给这些类或者结构体提供一个默认构造器,这个构造器会简单地创建一个所有属性值都设置为默认值的实例。看官方的Swift书是这么说的。 下面例子中创建了一个类 ShoppingListItem ,它封装了购物清单中的某一物品的属性:名字( name )、数量(

学如逆水行舟 539

CLR via C#-实例构造器

类的实例构造器 构造器是将类型的实例化为良好状态的特殊方法。 创建引用类型的实例 首先会为实例的数据字段分配内存。 然后初始化对象的附加字段(类型对象指针和同步块索引)。 最后调用类型的实例构造器来设置对象的初始状态。 构造器初始化字段为0或null 构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归零。 没有被构造器显式重写的所有字段保证都获得...

weixin_30764771的博客 189

跟小静读CLR via C#(06)- 构造器

跟小静读CLR via C#(06)-构造器 最近忙着看新还珠,好几天不学习了。玩物丧志啊,罪过罪过。 今天总结的是类构造器的知识,其实这方面的文章蛮多的,可还是觉得亲自写一下对自己的思考和认识会有提高。 对于构造器,大家应该都不陌生,它主要是用来进行初始化状态的。包括实例构造器和类构造器两种,先给大家看个实际的例子。 class Dog : A...

weixin_34270606的博客 149
上一篇: 基类中virtual与派生类中的override、new
下一篇: override与new(用两个小例子来解释)
hongyanjava
博客等级 码龄17年 12粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值