C# 学习笔记-基础与变量

《Csharp 8.0 and .NET Core 3.0 – Modern Cross-Platform Development 4th Edition》第二章

基础与变量

不涉及高级和晦涩的主题,例如 ref 局部变量重新分配和值类型的引用语义。

基础

用反射获取类型数量:

using System.Linq;
using System.Reflection;namespace ConsoleApp
{class Console1{static void Main(String[] args){foreach (var r in Assembly.GetEntryAssembly().GetReferencedAssemblies()){var a = Assembly.Load(new AssemblyName(r.FullName));int methodCount = 0;foreach (var t in a.DefinedTypes){methodCount += t.GetMethods().Count();}Console.WriteLine("{0:N0} types with {1:N0} methods in {2} assembly.",arg0: a.DefinedTypes.Count(),arg1: methodCount,arg2: r.Name);}}}
}

输出:

0 types with 0 methods in System.Runtime assembly.
108 types with 1,141 methods in System.Linq assembly.
46 types with 670 methods in System.Console assembly.

定义一些来自其他 assembilies 的类型的变量,这些 assembilies 将被加载到我们的应用中。将以下变量定义在 Main 函数的开头,然后重新运行上面的程序:

System.Data.DataSet ds;
System.Net.Http.HttpClient client;

得到:

0 types with 0 methods in System.Runtime assembly.
400 types with 7,038 methods in System.Data.Common assembly.
426 types with 4,613 methods in System.Net.Http assembly.
108 types with 1,141 methods in System.Linq assembly.
46 types with 670 methods in System.Console assembly.

变量

我们总在与数据打交道,数据在程序中往往存储在变量中,它们占用了内存并会在程序结束时释放内存。

我们在使用变量时,应该考虑两件事:1. 它用了多少内存;2. 它将被如何处理。

我们通过选择合适的类型来控制这两件事情。

小内存的类型并不一定比大内存的类型更快,比如 16 bit 的整数在 64 位系统上没有 64 bit 的证书快。

命名

小写开头驼峰法(Camel case),用于局部变量;私有字段;

大写开头(Title case),用于类型、非私有字段和其他成员如函数。

在 C#6.0 中引入了关键字 nameof 来查看变量名。

double heightInMetres = 1.88;
Console.WriteLine($"The variable {nameof(heightInMetres)} has the value {heightInMetres}.");

字面值

Literal values

存储文本

首先是字符,单个字母,用 char 类型存储,通过 加单引号表示对应的字面值,例如:

char letter = 'A';
char digit = '1';
char symbol = '$';

多个字符组成字符串,使用 string 类型存储,双引号表示对应的字面值,例如:

string firstName = "Bob";

字符串还有一些转义字符时,但是只想当作普通字符串用,则需要 @ 作为字符串前缀关闭字符串的转义:

string filePath = @"C:\televisions\sony\bravia.txt";

之前还演示过格式字符串:

string s = $"The variable {nameof(heightInMetres)} has the value {heightInMetres}.";

存储数字

uint naturalNumber = 23;
int integerNumber = -23;// F 后缀表示单精度浮点数字面值
float realNumber = 2.3F; 
double anotherRealNumber = 2.3;

在 C#7.0 中允许使用 _ 来分割整数(无论什么进制),如 1_000_000

  • 二进制字面量以0b 开头:0b_0001_1110
  • 十六进制字面量以0x 开头:0x_001E_8480
  • F 后缀表示单精度浮点数字面值
  • M 后缀表示 decimal 字面值

decimal 为 16 bytes 的小数,范围没有 double 大,但是可以进行精准的小数等号比较。

注意!double 受精度限制,不能与其他值进行等号比较。

double 有一些特殊值:double.NaN 表示非数字,double.Epsilon 是可以用一个 double 表示的最小的正数。double.Infinity 表示无限大数。

浮点数大都采用 IEEE 754 标准设计浮点数。

C# 有操作符 sizeof() 来获取一个类型使用的 byte 数;一些类型有 MaxValueMinValue 成员,来获取该类型可表达的最大和最小值。

一个例子来查看这些类型的信息:

Console.WriteLine($"int uses {sizeof(int)} bytes and can store numbers in the range {int.MinValue:N0} to {int.MaxValue:N0}.");
Console.WriteLine($"double uses {sizeof(double)} bytes and can store numbers in the range {double.MinValue:N0} to {double.MaxValue:N0}.");
Console.WriteLine($"decimal uses {sizeof(decimal)} bytes and can store numbers in the range {decimal.MinValue:N0} to {decimal.MaxValue:N0}.");

输出:

int uses 4 bytes and can store numbers in the range -2,147,483,648 to 2,147,483,647.
double uses 8 bytes and can store numbers in the range -179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368 to 179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.
decimal uses 16 bytes and can store numbers in the range -79,228,162,514,264,337,593,543,950,335 to 79,228,162,514,264,337,593,543,950,335.

再次说明:decimal 为 16 bytes 的小数,范围没有 double 大,但是可以进行精准的小数等号比较。注意!double 受实现的精度限制,不能与其他值进行等号比较。

布尔值:bool happy = true;

object

有一种特殊类型叫 object,它能够存储任何类型的数据,但是灵活性的代价是更混乱的代码和可能较差的性能,所以应该尽可能避免。

object height = 1.88;
object name = "Amir";
Console.WriteLine($"{name} is {height} metres tall.");//int length1 = name.Length; // 编译器报错:error CS1061: “object”未包含“Length”的定义
int length2 = ((string)name).Length; // 转换到 string 类型在使用对应的方法
Console.WriteLine($"{name} has {length2} characters.");

动态类型

dynamic types

另一种能够存储任意类型数据的类型叫 dynamic,它的灵活性的代价是性能。dynamic 关键字自 C#4.0 引入。区别于 objectdynamic 能够直接调用对应的成员而无需显式类型转换。

dynamic anotherName = "Ahmed";
int length = anotherName.Length;
Console.WriteLine($"{anotherName} has {length} characters.");

在 VSCode 中编写时发现,dynamic 类型的数据无法得到 IntelliSense 智能感知,这是因为编译器无法在构建时检测 dynamic 的具体类型。取而代之的是,CLR 将会在运行时检查 dynamic 类型的成员,并可能再找不到成员时抛出异常。

局部变量

是指在函数中定义的变量,只在函数执行时存在,函数返回则释放内存。

准确的说:值类型会释放,但是引用类型必须等待垃圾回收(garbage collection)。

指定或推断一个局部变量的类型

可以使用 var 来进行类型推断,根据等号后面的字面值类型判断变量的类型,具体地:

  • 一个不带小数点的整数被推断为 int,如果有 L 后缀,则为 long
  • 一个带小数点的数默认被推断为 double,如果有 F 后缀,则为 float,如果有 M 后缀则为 decimal 类型。
  • 单引号括住表示 char 类型,双引号括住表示 string 类型
  • true false 表示 bool 类型。

良好实践:一般来说不建议使用 var ,因为这可能导致难以阅读;除非类型已经相当明显了。举例:

//好的使用,避免重复类型
var xml = new XmlDocument();
XmlDocument xml2 = new XmlDocument();//不好的使用,不容易让人知道类型
var file1 = File.CreateText(@"C:\something.txt");
StreamWriter file2 = File.CreateText(@"C:\something.txt");

获取类型的默认值

除了 string 外的大多数原始类型都是值类型(value types),这意味着它们必须有一个值。可以使用 default() 操作符确定一个类型的默认值。

string 是一个引用类型(reference type),这意味着 string 变量包含一个值(value)的内存地址而不是值(value)本身。一个引用类型可以有一个 null 值,表示一个变量还没有引用任何东西。null 是所有引用变量的默认值。

我们可以通过代码探究默认值:

Console.WriteLine($"default (int) = {default(int)}");
Console.WriteLine($"default (bool) = {default(bool)}");
Console.WriteLine($"default (DateTime) = {default(DateTime)}");
Console.WriteLine($"default (string) = {default(string)}");

输出:

default (int) = 0
default (bool) = False
default (DateTime) = 0001/1/1 0:00:00
default (string) = 

存储多个值(数组)

例子:

string[] names;
names = new string[4];
names[0] = "Kate";
names[1] = "Jack";
names[2] = "Rebecca";
names[3] = "Tom";
for (int i = 0; i < names.Length; i++)
{Console.WriteLine(names[i]);
}

数组在内存分配时始终具有固定大小,因此需要在实例化它们之前决定要存储多少项。

collections 是一个更灵活的数组,之后介绍。

空值 null

您现在已经了解了如何在变量中存储原始值(例如数字)。但是如果变量还没有值怎么办?我们如何表明这一点? C#有空值(null)的概念,它可以用来表示变量还没有被设置。

让值类型可空

默认情况下,像 int DateTime 这样的值类型必须始终有一个值,因此得名。但是,比如有时读取数据库时可能得到一个空的值,为了便捷允许一个值类型为 null,我们称之为可空值类型(nullable value type)。

声明可空值类型时在类型后面加一个 ? 。例如:

//int thisCannotBeNull = 4;
//thisCannotBeNull = null; //编译报错int? thisCouldBeNull = null;
Console.WriteLine(thisCouldBeNull);
Console.WriteLine(thisCouldBeNull.GetValueOrDefault());thisCouldBeNull = 7;
Console.WriteLine(thisCouldBeNull);
Console.WriteLine(thisCouldBeNull.GetValueOrDefault());

输出:

0
7
7

null 什么都不输出

可空/不可空引用类型

在许多语言中,空值的使用非常普遍,以至于许多经验丰富的程序员从不质疑它存在的必要性。但在很多情况下,如果变量不允许有空值,我们可以编写更好、更简单的代码。

C# 8.0 中对该语言最重要的变化是引入了可为 null 和不可为 null 的引用类型。 在 C# 8.0 中,可以通过设置文件级或项目级选项来将引用类型配置为不再允许 null 值。

注意:使能该特性意味着引用类型和值类型一样不可空,但是可以使用 ? 后缀使之可空。

<Nullable>enable</Nullable>#nullable enable 是指默认不可空,而不是可空。具体什么意思还不懂可以往下看。

项目级设置可空,需要在项目文件 xx.csproj 中添加:

<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>

文件级设置,需要在文件顶部加入:

#nullable disable
#nullable enable

声明不可空变量或参数

当项目级和文件设置可控为 enable 时:

<Nullable>enable</Nullable>#nullable enable

我们定义如下类:

class Address
{public string? Building;public string Street;public string City;public string Region;
}

会发现后面的三个字段:Street、City、Region 都被提出了警告:

在退出构造函数时,不可为 null 的 字段“Street”必须包含非 null 值。请考虑将 字段 声明为可以为 null。

在 Main 函数中定义一个实例并设置属性:

var address = new Address();
address.Building = null;
address.Street = null;
address.City = "London";
address.Region = null;

Street Region 给出警告:

无法将 null 字面量转换为非 null 的引用类型。

因此,这就是新语言功能被命名为可为空引用类型的原因。从 C# 8.0 开始,未修饰的引用类型可以变为不可为 null,并且使用与值类型相同的语法使引用类型可以为 null。

如果是

#nullable disable

呢?

那么上述代码只会有一个警告,来自 public string? Building;

只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。

在.NET8.0中,该特性默认开启。

检查 null

如果不检查 null,就可能引发 NullReferenceException 异常。

检查 null 的代码如下所示:

// check that the variable is not null before using it
{if (thisCouldBeNull != null)// access a member of thisCouldBeNullint length = thisCouldBeNull.Length; // could throw exception...
}

如果你尝试使用一个可能为空的变量的成员,使用 null 条件操作符 ?,如下所示:

string authorName = null;
// 下面这行会抛出 NullReferenceException
int x = authorName.Length;
// 不会抛出异常了, null 被赋给 y
int? y = authorName?.Length;

有时,您想要将变量赋给结果或使用替代值,例如 3(如果变量为 null)。可以使用 null-coalescing 运算符 ??

// 如果 authorName?.Length 是空,那么就用 3 代替
var result = authorName?.Length ?? 3;
Console.WriteLine(result);

关于该运算符的更多资料:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator

关于控制台应用的更多

控制台应用程序是基于文本的,并在命令行上运行。它们通常执行需要编写脚本的简单任务,例如编译文件或加密配置文件的一部分。

如果像创建 F# 语言的控制台程序,可以使用:

dotnet new console -lang "F#" -name "ExploringConsole"

打印信息时,也可以使用 Console.Write 函数,它不会在最后输出换行符。

使用数字的位置参数格式化

Formatting using numbered positional arguments

生成格式化字符串的一种方法是使用数字化位置参数。

该特性被像 Write WriteLine 的函数支持,如果函数不支持,可以用 string Format 方法。

例如:

int numberOfApples = 12;
decimal pricePerApple = 0.35M;
Console.WriteLine(format: "{0} apples costs {1:C}",arg0: numberOfApples,arg1: pricePerApple * numberOfApples);
string formatted = string.Format(format: "{0} apples costs {1:C}",arg0: numberOfApples,arg1: pricePerApple * numberOfApples);
//WriteToFile(formatted); // WriteToFile并不存在,仅作演示

使用内插字符串进行格式化

Formatting using interpolated strings

C#6.0 及之后版本有一个方便的特性叫内插字符串(interpolated strings)。一个使用 $ 作为前缀的 string 可是使用 大括号将表达式的值输出到字符串对应的位置。

例如:

Console.WriteLine($"{numberOfApples} apples costs {pricePerApple *numberOfApples:C}");

对于短字符串来说这样很好理解。但是长字符串不容易换行,难以阅读,这时候可以用前面说的数字化位置参数。

格式化字符串

可以使用逗号或冒号后面的格式字符串来格式化变量或表达式。

一个 N0 格式字符串表示一个有着千位分隔符且没有小数点的数字;c 格式字符串表示货币。货币格式化将有当前线程(地区?)确定。例如,如果您在英国的 PC 上运行此代码,您将得到以逗号作为千位分隔符的英镑,但如果您在德国的 PC 上运行此代码,您将得到以点作为千位分隔符的欧元。

格式项的完整语法是:

{index [, alignment] [ : formatString]}

每个格式化项可以有一个对齐,在字符宽度内左对齐或右对齐。对齐数值(alignment values)是一个整数,正整数表示右对齐,而负整数表示右对齐。

例子:

string applesText = "Apples";
int applesCount = 1234;
string bananasText = "Bananas";
int bananasCount = 56789;Console.WriteLine(format: "{0,-8} {1,6:N0}",arg0:"Name",arg1:"Count"
);
Console.WriteLine(format: "{0,-8} {1,6:N0}",arg0:applesText,arg1:applesCount
);
Console.WriteLine(format: "{0,-8} {1,6:N0}",arg0:bananasText,arg1:bananasCount
);

输出:

Name      Count
Apples    1,234
Bananas  56,789

获取用户输入

使用 ReadLine 方法获取用户输入,用户输入完毕后按下回车,该函数返回一个 string

例子:

Console.Write("Type your first name and press ENTER: ");
string firstName = Console.ReadLine();Console.Write("Type your age and press ENTER: ");
string age = Console.ReadLine();Console.WriteLine($"Hello {firstName}, you look good for {age}."
);

输出:

Type your first name and press ENTER: Peter
Type your age and press ENTER: 24
Hello Peter, you look good for 24.

导入名称空间

和 C++ 的名称空间作用类似。

System 空间限制被默认导入。

C#6.0之后, using 声明用来进一步简化我们的代码。

using static System.Console;

这样,我们就不用写 Console 了。

获取用户的 按键 输入

使用函数 ReadKey 获取按键,按下任意按键立刻返回 string

例如:

Write("Press any key combination: ");
ConsoleKeyInfo key = ReadKey();
WriteLine();
WriteLine("Key: {0}, Char: {1}, Modifiers: {2}",arg0: key.Key,arg1: key.KeyChar,arg2: key.Modifiers);

运行后,按下 k 键:

Press any key combination: k
Key: K, Char: k, Modifiers: 0

按下 Shift + k:

Press any key combination: K
Key: K, Char: K, Modifiers: Shift

按下 F12:

Press any key combination: 
Key: F12, Char: , Modifiers: 0

获取命令行参数

命令行参数通过空格分割,其他字符(如连字符和冒号)被视为参数值的一部分。要在参数值中包含空格,请将参数值用单引号或双引号引起来。

举例:

using System;
using static System.Console;
namespace Arguments
{class Program{static void Main(string[] args){WriteLine($"There are {args.Length} arguments.");foreach (string arg in args)WriteLine(arg);}}}
}

运行时使用:dotnet run firstarg second-arg third:arg "fourth arg",得到输出:

There are 4 arguments.
firstarg
second-arg
third:arg
fourth arg

比如,我们想通过命令行参数设置输出窗口的背景颜色、前景颜色、宽度、高度。导入的 System 名称空间包含 ConsoleColor 和 Enum 类型:

if (args.Length < 4) 
{WriteLine("You must specify two colors and dimensions,e.g.");WriteLine("dotnet run red yellow 80 40");return; // stop running
}
ForegroundColor = (ConsoleColor)Enum.Parse(enumType: typeof(ConsoleColor),value: args[0],ignoreCase: true);BackgroundColor = (ConsoleColor)Enum.Parse(enumType: typeof(ConsoleColor),value: args[1],ignoreCase: true);
WindowWidth = int.Parse(args[2]);
WindowHeight = int.Parse(args[3]);

然后运行以下命令即可改变颜色:

dotnet run red yellow 50 10

尽管编译器没有给出错误或警告,但在运行时,某些 API 调用可能会在某些平台上失败。尽管在 Windows 上运行的控制台应用程序可以更改其大小,但在 macOS 上却不能。

处理不支持 API 的平台

遇到这种问题,我们可以用异常处理来解决。例如:

try
{WindowWidth = int.Parse(args[2]);WindowHeight = int.Parse(args[3]);
}
catch (PlatformNotSupportedException)
{WriteLine("The current platform does not support changing the size of a console window.");
}

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

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

相关文章

Swagger 教程:从零开始学习Swagger

Swagger 是一个开源的 API 设计和文档工具&#xff0c;可以帮助全栈工程师更快、更简单地设计、构建、文档化和测试 RESTful API。本篇文章将为全栈工程师介绍 Swagger 的基础知识和使用方法&#xff0c;以及如何使用 Swagger 设计、文档化和测试 RESTful API。 一、Swagger 简…

SLF4J Spring Boot日志框架

JAVA日志框架 JAVA有好多优秀的日志框架&#xff0c;比如log4j、log4j2、logback、JUL&#xff08;java.util.logging&#xff09;、JCL&#xff08;JAVA Common Logging&#xff09;等等&#xff0c;logback是后起之秀&#xff0c;是Spring Boot默认日志框架。 今天文章的目…

oracle19c容器数据库rman备份特性-----性能优化(三)

目录 冗余备份片 1.备份的时候指定 2.rman配置中设定 归档备份&#xff08;将备份集保留&#xff09; 二级备份&#xff08;将备份文件保留&#xff09; 1.备份闪回恢复区的恢复文件 2.备份所有恢复文件 recovery catalog database 1.創建recovery catalog 2.创建VPC…

zabbix-proxy代理安装及其他监控方式

zabbix-proxy代理安装及其他监控方式 安装zabbix-proxyserver端配置zabbix-proxy配置被监控的agent安装中问题解决监控网络设备JMX和IPMI监控方式 zabbix-proxy的安装&#xff0c;至少需要准备三台机器&#xff0c;一台安装服务端&#xff0c;一台安装agent端&#xff0c;这里就…

《网络是怎样连接的》2.3节图表(自用)

图4.1&#xff1a;TCP拆分数据与ACK号 图4.2&#xff1a;连接阶段与通信阶段ACK号与序号的交互过程 首先&#xff0c;客户端在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值&#xff0c;并将这个值发送给服务器&#xff08;①&#xff09;。 接下来&#xff0c…

基于SpringBoot的企业OA管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的企业OA管理系统,java项…

【C++PCL】点云处理LCCP分割

作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 本专栏特色:根据经验和大家分享每个参数的调试规范,解决大家因为参数的问题而产生的苦恼。 目录 1.原理介绍 2.代码效果 3.源码展示

HTTP协议九种请求方法的异同

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;定义了多种请求方法&#xff08;也称为HTTP方法或动作&#xff09;&#xff0c;用于指定客户端对服务器执行的操作。以下是HTTP协议中常见的九种请求方法&#xff1a; 1. **GET&#xff1a;** - 用于请求指定的资源…

在k8s集群中部署多nginx-ingress

关于ingress的介绍&#xff0c;前面已经详细讲过了&#xff0c;参考ingress-nginx详解和部署方案。本案例ingress的部署使用deploymentLB的方式。 参考链接&#xff1a; 多个ingress部署 文章目录 1. 下载ingress的文件2. 文件资源分析3. 部署ingress3.1 部署第一套ingress3.1…

C# 反射的乌云,MethodInfo的Json序列化参数入参问题

文章目录 前言直接运行MethodInfo运行结果 Json解决ParamterInfo实例化运行结果无法实例化问题部分参数的问题 Json反序列化 经过长达一天的研究&#xff0c;我终于完全的解决的了实战思路方法测试用例运行测试运行结果 代码总结总结 前言 我上篇文章已经基本解决了反射的基本…

众和策略:沪指跌0.91%险守2900点,半导体、金融等板块走低

8日早盘&#xff0c;两市股指低开低走&#xff0c;沪指一度失守2900点&#xff0c;深成指、创业板指跌约1%&#xff0c;科创50指数创前史新低。 到午间收盘&#xff0c;沪指跌0.91%报2902.4点&#xff0c;深成指跌1.17%&#xff0c;创业板指跌0.99%&#xff0c;科创50指数跌超…

python每日学12:面向对象的编程

背景&#xff1a;最近有些时间&#xff0c;打算把python每日学的计划继续执行起来。由于不知道从何入手&#xff0c;就暂定从学习《python学习手册》开始&#xff0c;这本书也是python领域的一本权威著作&#xff0c;各方面都写的非常详细&#xff0c;读起来很有帮助&#xff0…

pythonPandas四:数据操作与转换

当涉及到数据操作和转换时&#xff0c;Pandas提供了许多有用的功能。以下是一些示例说明&#xff1a; 1.数据选择和操作&#xff1a; import pandas as pd# 创建一个示例DataFrame data {Name: [Alice, Bob, Charlie],Age: [25, 30, 35],City: [New York, London, Paris]} d…

HTTP 请求参数之三种格式

Query String Parameters 、Form Data 、 Request Payload 三种格式的区别。主要是因为 Content-Type&#xff08;用于表明发送数据流的类型&#xff09; 与请求方式 method 不同&#xff0c;导致传递的数据格式不同。 1. Query String Parameters 格式&#xff1a; ?keyvalu…

07GoF之三种工厂模式

GoF&#xff08;Gang of Four&#xff09;:四人组,《Design Patterns: Elements of Reusable Object-Oriented Software》&#xff08;《设计模式》)的作者,设计了23种设计模式.但时代发展,还有其它的设计模式&#xff0c;比如&#xff1a;JavaEE的设计模式&#xff08;DAO模式…

VSCode安装GitHub Copilot插件方法

VSCode安装GitHub Copilot插件的步骤及注意事项如下&#xff1a; 安装步骤&#xff1a; 确保系统要求&#xff1a; 确保你正在使用的Visual Studio Code版本是最新的&#xff0c;且支持GitHub Copilot。同时&#xff0c;Copilot需要你的操作系统是Windows、macOS或Linux&#x…

如何通过PreMaint状态监测发现设备故障:以振动监测为例

在现代工业环境中&#xff0c;设备的健康状况对于维持生产效率至关重要。计划外停机可能导致巨大的成本损失&#xff0c;因此采用先进的监测技术成为预防性维护的核心策略之一。其中&#xff0c;振动监测作为一种早期故障检测手段&#xff0c;通过PreMaint状态监测系统的引入&a…

【前端面试题】每日一个前端面试专题

一、typeof 与 instanceof 区别?如何instanceof的原理 问题回答思路 typeof和instanceof 都可以检测数据类型&#xff0c;typeof检测如果是基本数据类型返回对应的结果。如果检测是对象的话&#xff0c;默认返回一个object&#xff0c;所以无法区分那种对象。 typeof 数据ins…

组件封装原则

在Vue中封装组件时&#xff0c;遵循低耦合、高内聚、可扩展性和可维护性的原则非常重要。以下是一些实现这些原则的关键点&#xff0c;并结合Vue的实践方式给出案例说明&#xff1a; 1. 单一职责原则&#xff1a; 每个组件专注于一个特定的功能或UI部分&#xff0c;例如&#…

Java动态代理机制,创建代理对象的方法(InvocationHandler,Proxy)

目录 1.什么是动态代理2.如何为Java对象创建一个代理对象 1.什么是动态代理 特点&#xff1a;无侵入式的给代码增加额外的功能。 在Java中&#xff0c;动态代理是一种机制&#xff0c;允许在运行时创建一个代理对象来代替原始对象&#xff0c;并可以在代理对象的方法执行前后追…