文章目录

  • 前言
  • 一、构造函数是什么?
  • 二、构造函数的用法
    • 1.初始化对象,避免无效状态
    • 2 初始化静态成员
    • 3 构造函数重载
    • 4.构造函数链
    • 5. 单例模式,多次实例化保持一个对象
    • 6. 依赖注入
    • 7. 初始化只读对象


前言

构造函数是我们平常编程里经常能碰到的老伙计了,构造函数本质上是类中一种特殊的成员方法,用于在实例化对象的时候,对该类中的一些状态进行初始化。本篇文章总结下工作中经常能碰到的使用构成函数的场景,希望能帮助到大家。

一、构造函数是什么?

构造函数可以理解成一个特殊的方法,当一个类被实例化时,这个构造函数会被自动调用,用作初始化这个对象。但是,构造函数的功能根据应用场景,可以扩展为不同的用法。

二、构造函数的用法

1.初始化对象,避免无效状态

很多时候初始化对象,需要给对象设定一种状态,我哪一种业务逻辑举例。卖出去的商品价格不能为负数,库存数量也不能小于零。

这里构造函数最的作用是保证商品对象在创建时就处于有效状态,避免因价格设置错误,库存数量设置错误导致后续逻辑出错,作为一个业务逻辑的检验之用。

internal class Product
{public string productId { get; }/// <summary>/// 价格 > 0/// </summary>public double price { get;  }/// <summary>/// 库存 > 0/// </summary>public int stock { get; }// 构造函数:初始化+参数校验public Product(String productId, double price, int stock){this.productId = productId;// 校验价格合法性,非法则抛出异常,阻止对象创建if (price < 0){throw new ArgumentOutOfRangeException("商品价格不能为负数:" + price);}this.price = price;// 校验库存合法性if (stock < 0){throw new ArgumentOutOfRangeException("商品库存不能为负数:" + stock);}this.stock = stock;}
}

2 初始化静态成员

静态变量,静态属性这类成员属于类本身,而非类的实例。它的初始化方式就是通过构造函数初始化的。确保了静态成员在类的整个生命周期中保持一致的初始状态,适合存储全局共享的数据。

比方说一个日志类需要一个属性存放文件目录,用静态属性的方式就很合适,使用构造函数初始化静态成员。

internal class log
{public static string PhyPath { get; private set; }static log(){PhyPath = AppDomain.CurrentDomain.BaseDirectory;}
}

3 构造函数重载

构造函数重载允许一个类定义多个构造函数,这些构造函数具有相同的名称但参数不同,包括不限于参数个数,参数类型,参数顺序。这是一种灵活的初始化方式,从而应对实例化的时候的各种场景。

这里提供两种构造函数,一个参数是包含电影名称和描述信息,另一个构造函数只包含电影名称,这样实例化Movie类的时候,就能通过两种方式实例化Movie。为对象提供多种初始化方式,满足不同场景的需求

internal class Movie
{public int Id { get; set; }public string MovieName { get; set; }public string Desc { get; set; }public Movie(string MovieName){this.MovieName = MovieName;this.Desc = "";}public Movie(string MovieName,string Desc){this.MovieName = MovieName;this.Desc = Desc;}}

4.构造函数链

子类继承父类的时候,子类可以通过base关键字调用父类的构造函数,实现子类向父类传递参数的情况,也能避免重复代码。

比方说我有一个父类,提供一个构造函数,子类可以通过调用父类的构造函数实现状态的配置化。

/// 父类
public BaseClass(String HttpMethod)
{if (HttpMethod.ToUpper() == "GET"){_httpRequest = HttpContext.Current.Request.QueryString;}if (HttpMethod.ToUpper() == "POST"){_httpRequest = HttpContext.Current.Request.Form;}
}/// 子类
public ChiledClass() : base(HttpContext.Current.Request.HttpMethod)
{
}

5. 单例模式,多次实例化保持一个对象

在数据操作这类服务,经常是能碰到使用单例模式的场景。多次实例化一个数据服务对象,返回的任然是同一个实例,禁止外部直接创建对象。这样既能保证资源利用的最大化,并且类能自主控制创建规则,保证代码安全性。

比方说初始化一个RedisServer服务,其构造函数是私有的,无法直接通过初始化的时候执行这个构造函数。通过Lazy这延迟初始化工具,确保RedisServer实例在首次被使用时通过调用内部私有的构造函数创建,实现 “懒加载”。最后通过一个静态实例返回lazy.Value 实现单例模式

/// <summary>
/// Redis单例服务
/// </summary>
public sealed class RedisServer
{//私有静态字段,存储唯一实例private static readonly Lazy<RedisServer> lazy = new Lazy<RedisServer>(() => new RedisServer());/// <summary>/// 静态实例/// </summary>public static RedisServer Instance { get { return lazy.Value; } }/// <summary>/// Redis连接对象/// </summary>private readonly ConnectionMultiplexer _redis;/// <summary>/// Redis数据库对象/// </summary>private readonly IDatabase _db;/// <summary>/// Redis单例服务/// </summary>private RedisServer(){/// 逻辑:/// 1. 创建Redis连接对象/// 2. 创建Redis数据库对象}/// <summary>/// 获取Redis数据库对象/// </summary>public IDatabase GetDatabase(){return _db;}
}

6. 依赖注入

依赖注入中,也可以是通过构造函数来实现接收依赖项的。另外就是这里通过构造函数初始化只读属性,这样可以创建不可变对象,实现线程安全。

[Route("api/[controller]/[action]")]
[ApiController]
public class AuthController : ControllerBase
{private readonly ILogger<AuthController> _logger;private readonly IJWTService _jwtService;public AuthController(ILogger<AuthController> logger = null, IJWTService jwtService = null){_logger = logger;_jwtService = jwtService;}[HttpGet]public ActionResult<string> test(){return "test";}[HttpPost]public ActionResult<string> Login([FromBody]LoginUser loginUser) { var token =  _jwtService.GenerateToken(new CurrentUser() { UserId = loginUser.UserId,Name = "张三",Age = 18,NickName = "张三", RoleList = new List<string>() { "admin" } });return token;} 
}

7. 初始化只读对象

只能在构造函数中初始化readonly字段,创建不可变对象,实现线程安全。

代码如上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/94443.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/94443.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/94443.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM预训练架构全解析:从零构建一个语言世界的“操作系统”

导读&#xff1a;作为开发者&#xff0c;我们每天都在import或#include各种库&#xff0c;我们信任这些由无数代码构成的底层依赖。那么&#xff0c;当我们调用一个LLM时&#xff0c;它所依赖的那个更底层的、无形的**“语言操作系统”**&#xff0c;又是如何被“编译”出来的&…

Linux服务测试题(DNS,NFS,DHCP,HTTP)

一&#xff0c;实验拓扑&#xff1a;二&#xff0c;需求APPSRV&#xff1a;主机名&#xff1a;appsrv.example.comip地址&#xff1a;192.168.100.10网关&#xff1a;192.168.100.254网卡为NAT模式STORAGESRV&#xff1a;主机名&#xff1a;storagesrv.example.comip地址&#…

DevOps 简介及就业前景

DevOps 简介及就业前景 目录 DevOps简介核心概念重难点解析具体场景使用就业前景学习路径最佳实践 DevOps简介 什么是DevOps DevOps是Development&#xff08;开发&#xff09;和Operations&#xff08;运维&#xff09;的组合词&#xff0c;是一种软件开发和IT运维的文化…

《CF1120D Power Tree》

题目描述 给定一棵有 n 个顶点的有根树&#xff0c;树的根为顶点 1。每个顶点都有一个非负的价格。树的叶子是指度为 1 且不是根的顶点。 Arkady 和 Vasily 在树上玩一个奇怪的游戏。游戏分为三个阶段。第一阶段&#xff0c;Arkady 购买树上的一些非空顶点集合。第二阶段&…

CPTS-Agile (Werkzeug / Flask Debug)

枚举 nmap -sC -sV -T4 -Pn -n -p- 10.10.11.203进行常规的网页枚举和测试发现报错信息&#xff0c;‘Werkzeug / Flask Debug’ 测试Export导出功能发现存在路径遍历查看这篇文章 https://book.hacktricks.wiki/zh/network-services-pentesting/pentesting-web/werkzeug.html#…

【网络运维】Shell 脚本编程:while 循环与 until 循环

Shell 脚本编程&#xff1a;while 循环与 until 循环 循环结构简介 循环语句是 Shell 脚本中用于重复执行一条或一组指令的重要工具&#xff0c;直到满足特定条件时停止执行。Shell 脚本中常见的循环语句包括 while、until、for 和 select。本文将重点介绍 while 和 until 两种…

LLM 中评价指标与训练概要介绍

在【LLM】LLM 中增量解码与模型推理解读一文中对 LLM 常见名词进行了介绍&#xff0c;本文会对 LLM 中评价指标与训练概要进行介绍&#xff0c;本文并未介绍训练实操细节&#xff0c;未来有机会再了解&#xff5e; 一、LLM 如何停止输出 在看 LLM 评价指标前&#xff0c;先看…

Java 20 新特性及具体应用

目录 1. 模式匹配 for switch&#xff08;预览特性&#xff09; 2. 记录模式&#xff08;预览特性&#xff09; 3. 外部函数与内存 API&#xff08;预览特性&#xff09; 4. 矢量 API&#xff08;孵化器特性&#xff09; 5. 作用域值&#xff08;预览特性&#xff09; 6. …

【STM32】CubeMX(十一):FreeRTOS任务挂起与解挂

这篇文章是 STM32 HAL FreeRTOS 下的任务挂起与恢复机制&#xff0c; 结合 CubeMX 图示与代码&#xff0c;构建了一个 FreeRTOS 控制示例。 本篇目标&#xff1a;创建两个任务&#xff1a; 一个控制蓝灯闪烁&#xff08;myTask01&#xff09; 另一个监控按键&#xff08;Start…

图片预加载:提升Web性能的关键

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

大模型压缩三剑客:量化、剪枝与知识蒸馏全解析

在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;如通义千问、GPT 等已成为推动智能应用的核心引擎。然而&#xff0c;这些模型动辄数十亿甚至上千亿参数&#xff0c;带来了高昂的计算成本和部署门槛。如何在不显著牺牲性能的前提下&#xff0c;让大…

Seaborn数据可视化实战:Seaborn基础图表绘制入门

基础图表绘制&#xff1a;Seaborn入门教程 学习目标 通过本课程的学习&#xff0c;你将掌握如何使用Seaborn库绘制基础图表&#xff0c;包括条形图、折线图和散点图。你将了解Seaborn的基本函数和参数设置&#xff0c;以及如何通过调整这些参数来优化图表的视觉效果。 相关知识…

阿里开源通义万相Wan2.2:视频生成技术的革命性突破

在人工智能视频生成领域,阿里云通义实验室于2025年7月重磅开源了新一代视频生成大模型 Wan2.2,其核心亮点包括人体动作生成的极致精度、电影级美学表达以及高效的资源利用效率,标志着视频生成技术迈入了一个全新的阶段。 一、核心功能:三大模型,覆盖全场景视频生成 Wan2.…

说说你对Integer缓存的理解?

大家好&#xff0c;我是锋哥。今天分享关于【说说你对Integer缓存的理解?】面试题。希望对大家有帮助&#xff1b; 说说你对Integer缓存的理解? 超硬核AI学习资料&#xff0c;现在永久免费了&#xff01; Integer 缓存是 Java 中一个优化机制&#xff0c;它主要通过缓存一部…

高速CANFD收发器ASM1042在割草机器人轮毂电机通信系统中的适配性研究

摘要割草机器人轮毂电机的通信系统对其实现自主控制和高效作业至关重要。本文旨在研究国科安芯推出的高速CANFD收发器芯片ASM1042是否能够满足割草机器人轮毂电机通信系统的复杂需求。通过详细分析轮毂电机通信系统的性能要求&#xff0c;以及ASM1042的电气、功能和环境特性&am…

MTK Linux DRM分析(十二)- KMS Panel框架层(drm_panel.c、drm_mipi_dbi.c、drm_mipi_dsi.c)

一、简介 三个代码文件(drm_mipi_dbi.c、drm_panel.c、drm_mipi_dsi.c)的分析。这些文件都是Linux内核DRM(Direct Rendering Manager)子系统的组成部分,主要用于支持显示面板,特别是通过MIPI(Mobile Industry Processor Interface)接口的显示设备。它们提供了显示驱动…

合合信息acge模型获C-MTEB第一,文本向量化迎来新突破

前言&#xff1a; 在当今时代&#xff0c;大型语言模型以其惊人的发展速度和广泛的应用前景&#xff0c;正成为全球科技界的瞩目焦点。这些模型的强大能力&#xff0c;源自于背后默默支撑它们的Embedding技术——一种将语言转化为机器可理解的数值向量的关键技术。随着大型语言…

26.内置构造函数

2.内置构造函数2.1Object2.2Array2.3String2.4number

tauri配置允许执行eval脚本,在打包cocos游戏web/phone移动端的时候一定要配置

解决办法&#xff1a;在tauriconfig中配置"csp": "default-src self asset: unsafe-inline customprotocol://* http://localhost:* ws:localhost:* unsafe-eval ipc: http://ipc.localhost; script-src unsafe-eval self https://www.googletagmanager.com uns…

K 均值聚类算法学习总结

一、聚类算法基础认知 核心概念&#xff1a;聚类属于无监督学习&#xff0c;核心是把 “相似的样本” 自动分到同一组&#xff08;簇&#xff09;&#xff0c;不需要预先标注的标签。主要挑战是怎么定义 “相似性”、评估聚类效果以及确定最好的聚类数量。 距离度量&#xff1a…