【C#学习笔记】值类型(1)
虽然拥有编程基础的人可以很快地上手C#,但是依然需要学习C#的特性和基础。本系列是本人学习C#的笔记,完全按照微软官方文档编写,但是不适合没有编程基础的人。
文章目录
- .NET 体系结构
- Hello,World
- 类型和变量(重要)
- 什么是值类型和引用类型?
- 值类型
- 简单类型
- 枚举类型
- 扩展方法
.NET 体系结构
C# 程序在 .NET 上运行,而 .NET 是名为公共语言运行时 (CLR) 的虚执行系统和一组类库。 CLR 是 Microsoft
对公共语言基础结构 (CLI) 国际标准的实现。 CLI 是创建执行和开发环境的基础,语言和库可以在其中无缝地协同工作。
简单来说,C#是在.NET上运行的,.NET是一个开发框架,框架内各种不同语言的代码可以互相交互,而C#中的数据类型定义遵循CTS以转化为CLR通用的数据类型。.NET提供了一个叫做CLR的虚拟机,CLR是基于CLI规范实现的虚拟运行时环境,而CLI是一个跨语言开发的规范,它定义了用于跨平台编译的中间语言IL,IL 代码和资源(如位图和字符串)存储在扩展名通常为 .dll 的程序集中,执行C#的时候通过在CLR执行实时 (JIT) 编译将IL转化为本机指令集从而实现跨平台。
Hello,World
using System;class Hello
{static void Main(){Console.WriteLine("Hello, World");}
}
上述是C#的 Hello,World。看起来就像是C++和Java的合体。
使用命名空间时使用的是using
关键字+命名空间名,随后我们定义了一个类,在其中定义了Main()
方法,Main
方法使用 static
修饰符进行声明。 实例方法可以使用关键字 this
引用特定的封闭对象实例,而静态方法则可以在不引用特定对象的情况下运行。 按照约定,Main
静态方法是 C# 程序的入口点。
好的,现在你已经学会C#了
类型和变量(重要)
C#中存在两大类型,一种是值类型,一种是引用类型。对这两种类型的理解是十分重要的。
值类型的变量直接包含它们的数据。 引用类型的变量存储对数据(称为“Object”)的引用。 对于引用类型,两个变量可以引用同一个对象;对一个变量执行的运算可能会影响另一个变量引用的对象。 借助值类型,每个变量都有自己的数据副本;因此,对一个变量执行的运算不会影响另一个变量(ref 和 out 参数变量除外)。
什么是值类型和引用类型?
原文链接:C# 如何避免装箱和拆箱操作
- 什么是值类型:
所有的结构都是抽象类型System.ValueType的直接派生类,而System.ValueType本身又是直接从System.Object派生的。根据定义所知,所有的值类型都必须从System.ValueType派生,所有的枚举都从System.Enum抽象类派生,而后者又从System.ValueType派生。
所有的值类型都是隐式密封的(sealed),目的是防止其他任何类型从值类型进行派生。
- 什么是引用类型:
在c#中所有的类都是引用类型,包括接口。
所以C#语言中的数据类型,实际上是从.NET的抽象基类中所派生的。
值类型
简单类型
- 有符号整型:sbyte、short、int、long
- 无符号整型:byte、ushort、uint、ulong
- Unicode 字符:char,表示 UTF-16 代码单元
- IEEE 二进制浮点:float、double
- 高精度十进制浮点数:decimal
- 布尔值:bool,表示布尔值(true 或 false)
枚举类型
- enum E {…} 格式的用户定义类型。 enum 类型是一种包含已命名常量的独特类型。 每个 enum 类型都有一个基础类型(必须是八种整型类型之一)。 enum 类型的值集与基础类型的值集相同。
结构类型
- 格式为 struct S {…} 的用户定义类型
- 可以为 null 的值类型
值为 null 的其他所有值类型的扩展 - 元组值类型
格式为 (T1, T2, …) 的用户定义类型
简单类型
简单类型包括整数型,浮点型,字符,布尔。也就是一些编程语言中的常用类型。
这些都是很基础的,可以看官方文档,其中特殊的类型是sbyte,byte,nint,nuint。后者是C# 11加入的,用于获取不同操作系统下本机正数范围大小:
对于 nint:Int32.MinValue 到 Int32.MaxValue。
对于 nuint:UInt32.MinValue 到 UInt32.MaxValue。
sbyte和byte的范围大小是1字节,sbyte包括了负数范围,但sbyte不符合CLR,所以我们只关注byte。byte与其他整数类型不同的是,直接赋值它一个ASCII字符,是不存在字符类型和byte类型的隐式和显式转换的,所以不可行,例如byte b='a'
。
对于整数型的数据,通常当数据溢出超过范围之后会改变(当然这和字节中的比特位变化相关)。例如byte型的255+1=0,sbyte的127+1= -128(特殊的,寄存器用00000000
表示0,而10000000
表示-128)
浮点数值类型之间只有一种隐式转换:从 float 到 double。 但是,可以使用显式强制转换将任何浮点类型转换为任何其他浮点类型。
在C#中,我们还可以用.NET类型定义或者跨语言,例如int a=1
和System.Int32 a=1
是一致的。
在为整数赋值时可以使用十进制,十六进制和二进制,十进制就是正常的数字,十六进制以0X
开头,二进制以0B
开头。我们在赋值时使用十进制也可以以_
作为分隔符,例如int a=3000
和int a =3_000
是等价的。
最后,大部分数字类型可以带有后缀字符,例如0.1f
用f代表float,21L
用L代表long。
枚举类型
枚举类型 是由基础整型数值类型的一组命名常量定义的值类型。 若要定义枚举类型,请使用 enum 关键字并指定枚举成员 的名称:
enum Season
{Spring,Summer,Autumn,Winter
}
一个枚举类型的变量的值只能是内部几种值之一。例如Season S1 =Season.Spring;
。直接打印会打印出枚举的成员名。但实质上枚举类型内的值对应着默认的整数,若无定义就从0开始从上往下依次递增,有定义则是定义的整数值。而使用枚举类型名也可以对整数值实现显式转换。
print(S1) // Spring
print((int)S1) // 0
var b = (Season)1;
Console.WriteLine(b); // output: Summer
枚举另一种表示方法是接受二进制表示,并可以用逻辑运算符按位运算,这是一般的用法。
而当我们使用[Flags]
指示可以将枚举指示为位域,枚举中的每个选项将称为一个位字段,此时通过逻辑运算符可以合并选项或交叉组合选项:
[Flags]
public enum Days
{None = 0b_0000_0000, // 0Monday = 0b_0000_0001, // 1Tuesday = 0b_0000_0010, // 2Wednesday = 0b_0000_0100, // 4Thursday = 0b_0000_1000, // 8Friday = 0b_0001_0000, // 16Saturday = 0b_0010_0000, // 32Sunday = 0b_0100_0000, // 64Weekend = Saturday | Sunday
}
public class FlagsEnumExample
{public static void Main(){Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;Console.WriteLine(meetingDays);// Output:// Monday, Wednesday, FridayDays workingFromHomeDays = Days.Thursday | Days.Friday;Console.WriteLine($"Join a meeting by phone on {meetingDays & workingFromHomeDays}");// Output:// Join a meeting by phone on Fridaybool isMeetingOnTuesday = (meetingDays & Days.Tuesday) == Days.Tuesday;Console.WriteLine($"Is there a meeting on Tuesday: {isMeetingOnTuesday}");// Output:// Is there a meeting on Tuesday: Falsevar a = (Days)37;Console.WriteLine(a);// Output:// Monday, Wednesday, Saturday}
}
扩展方法
在枚举类型中,通常我们不能定义方法,但是可以通过定义拓展方法来为现有类型“添加方法”而无需修改类型。而扩展方法就是用于对值类型的扩展的,例如想要为所有的string添加一个去掉空格的处理方法,不必定义一个类然后在里面定义方法和string变量。可以直接用扩展方法,但是按扩展方法必须满足的条件:
- 必须要静态类中的静态方法
- 第一个参数的类型是要扩展的类型,并且需要添加this关键字以标识其为扩展方法
通常,只在不得已的情况下才实现扩展方法,并谨慎的实现。扩展方法不能通过类名调用,而直接使用类型来调用。
namespace ExtensionMethods
{public static class MyExtensions{public static int WordCount(this string str){return str.Split(new char[] { ' ', '.', '?' },StringSplitOptions.RemoveEmptyEntries).Length;}}
}
// 上述扩展方法定义在了一个命名空间中的类中的一个方法,定义在命名空间中在调用时会更安全
// 在静态类中定义静态方法,并以添加this关键字标识类型传入
using ExtensionMethods;
string s = "Hello Extension Methods";
int i = s.WordCount();
在下例子中官方展示了一个绑定接口的拓展方法,任何继承这个接口的类,当其内部没有定义与拓展方法同名的方法时,就可以调用这个拓展方法。
// Define an interface named IMyInterface.
namespace DefineIMyInterface
{using System;public interface IMyInterface{// Any class that implements IMyInterface must define a method// that matches the following signature.void MethodB();}
}// Define extension methods for IMyInterface.
namespace Extensions
{using System;using DefineIMyInterface;// The following extension methods can be accessed by instances of any// class that implements IMyInterface.public static class Extension{public static void MethodA(this IMyInterface myInterface, int i){Console.WriteLine("Extension.MethodA(this IMyInterface myInterface, int i)");}public static void MethodA(this IMyInterface myInterface, string s){Console.WriteLine("Extension.MethodA(this IMyInterface myInterface, string s)");}// This method is never called in ExtensionMethodsDemo1, because each// of the three classes A, B, and C implements a method named MethodB// that has a matching signature.public static void MethodB(this IMyInterface myInterface){Console.WriteLine("Extension.MethodB(this IMyInterface myInterface)");}}
}// Define three classes that implement IMyInterface, and then use them to test
// the extension methods.
namespace ExtensionMethodsDemo1
{using System;using Extensions;using DefineIMyInterface;class A : IMyInterface{public void MethodB() { Console.WriteLine("A.MethodB()"); }}class B : IMyInterface{public void MethodB() { Console.WriteLine("B.MethodB()"); }public void MethodA(int i) { Console.WriteLine("B.MethodA(int i)"); }}class C : IMyInterface{public void MethodB() { Console.WriteLine("C.MethodB()"); }public void MethodA(object obj){Console.WriteLine("C.MethodA(object obj)");}}class ExtMethodDemo{static void Main(string[] args){// Declare an instance of class A, class B, and class C.A a = new A();B b = new B();C c = new C();// For a, b, and c, call the following methods:// -- MethodA with an int argument// -- MethodA with a string argument// -- MethodB with no argument.// A contains no MethodA, so each call to MethodA resolves to// the extension method that has a matching signature.a.MethodA(1); // Extension.MethodA(IMyInterface, int)a.MethodA("hello"); // Extension.MethodA(IMyInterface, string)// A has a method that matches the signature of the following call// to MethodB.a.MethodB(); // A.MethodB()// B has methods that match the signatures of the following// method calls.b.MethodA(1); // B.MethodA(int)b.MethodB(); // B.MethodB()// B has no matching method for the following call, but// class Extension does.b.MethodA("hello"); // Extension.MethodA(IMyInterface, string)// C contains an instance method that matches each of the following// method calls.c.MethodA(1); // C.MethodA(object)c.MethodA("hello"); // C.MethodA(object)c.MethodB(); // C.MethodB()}}
}
/* Output:Extension.MethodA(this IMyInterface myInterface, int i)Extension.MethodA(this IMyInterface myInterface, string s)A.MethodB()B.MethodA(int i)B.MethodB()Extension.MethodA(this IMyInterface myInterface, string s)C.MethodA(object obj)C.MethodA(object obj)C.MethodB()*/
相关文章:

【C#学习笔记】值类型(1)
虽然拥有编程基础的人可以很快地上手C#,但是依然需要学习C#的特性和基础。本系列是本人学习C#的笔记,完全按照微软官方文档编写,但是不适合没有编程基础的人。 文章目录 .NET 体系结构Hello,World类型和变量(重要&…...

二十三种设计模式第二十二篇--中介者模式
说到这个模式就有趣了,不知道大家在生活中喷到过中介没?其实中介这个词吧,我也说不上好还是坏,有时候他可以帮助人们更快的达到某个目的,但有的时候吧,这个有贼坑人,相信网络上有各种被中介坑的…...

小研究 - 微服务系统服务依赖发现技术综述(二)
微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…...
javaee 泛型的上下边界和通配符的使用
下边界 package com.test.generic;import java.util.Collection;public class TestGenericClass {//泛型方法 ? extends E :泛型的限定public static <E> void move(Collection<E> from,Collection<? super E> to){for(E e:from){to.add(e);}}public st…...

【TypeScript】类型声明及应用(二)
【TypeScript】类型声明及应用(二) 一、前言 TypeScript开发中需要对定义的变量指定类型,目前版本都支持哪些类型,每一个类型都有哪些含义,在这篇文章中,我们将会对其进行总结说明 二、JavaScript基本数据…...
rust from_utf8_lossy怎么使用?
from_utf8_lossy 是Rust标准库中的一个方法,用于将字节序列解码为UTF-8字符串。它的作用是尽可能地将无效的字节序列转换为有效的Unicode字符,以便进行后续处理。 以下是使用 from_utf8_lossy 方法的示例代码: fn main() {let bytes b"…...
#P0997. [NOIP2006普及组] 数列
题目描述 给定一个正整数k(3≤k≤15)k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k3k3时,这个序列是: 1,3,4,9,10,12,13,…1,3,4,9,10,12,13,… (该序列实际上就是&…...

做完两年外包,感觉自己废了一半....
先说一下自己的情况。大专生,17年通过校招进入湖南某软件公司,干了接近2年的点点点,今年年上旬,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了五年的功能测试…...

Kubernetes系列-Ingress
1 Ingress 概述 Kubernetes 对外暴露服务(Service)主要有两种方式:NodePort,LoadBalance,此外 externalIps 也可以使各类 service 对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺…...

软件测试之Docker常见问题汇总!附解决方法!
1、配置国内源进行docker安装,报错 HTTP Error 404 - Not Found 【整整200集】超超超详细的Python接口自动化测试进阶教程,真实模拟企业项目实战!! 原因: 由于配置国内镜像源时,把地址写错了,导…...
Python-操作Excel表-openpyxl模块使用
openpyxl简介 openpyxl是一个强大的Python库,用于读写Excel(xlsx/xlsm/xltx/xltm)文件。 主要功能和特点如下: 读取、修改、写入Excel文件,支持格式如xlsx、xlsm等支持 Excel 2003 以上格式可以很方便地遍历工作表中的行和列获取单元格对象后,可以修改单元格的值、样式、格式…...

向 Maven 中央仓库上传一个修改过的基于jeecg的autoPOI的 jar包记录
1、注册https://issues.sonatype.org/账号 下面就代表注册好了,同时提交的工单也通过了 2、这里主要是goupId 需要进行认证,需要到域名注册商近一个txt的解析,以便确保这个是你的 通过下面来验证你的域名信息,这里主要是上面的工…...

【HDFS】Block、BlockInfo、BlockInfoContiguous、BlockInfoStriped的分析记录
本文主要介绍如下内容: 关于几个Block类之间的继承、实现关系;针对文章标题中的每个类,细化到每个成员去注释分析列出、并详细分析BlockInfo抽象类提供的抽象方法、非抽象方法的功能针对几个跟块组织结构的方法再进行分析。moveBlockToHead、listInsert、listRemove等。一、…...

STM32 LoRa(学习二)
LoRa关键参数说明 LoRa数据包由三个部分组成:前导码、可选报头、数据有效负载。 前导码:用于保持接收机与输入的数据流同步。默认情况下,数据包含有12个符号长度的前导码。前导码是一个可以通过编程来设置的变量,所以前导码的长度…...

ASP.NET Core学习路线图
说明 1. 先决条件 - [C#](https://www.pluralsight.com/paths/csharp) - [Entity Framework](https://www.pluralsight.com/search?qentity%20framework%20core) - [ASP.NET Core](https://www.pluralsight.com/search?qasp.net%20core) - SQL基础知识 2. 通用开发技能 -…...

无涯教程-Lua - for语句函数
for 循环是一种重复控制结构,可让您有效地编写需要执行特定次数的循环。 for loop - 语法 Lua编程语言中 for 循环的语法如下- for init,max/min value, increment dostatement(s) end 这是 for 循环中的控制流程- 首先执行 init 步骤,并且仅执行一…...

二叉树的相关题目
目录 1、根据二叉树创建字符串 2、二叉树的层序遍历 3、二叉树的最近公共祖先 4、搜索二叉树与双向链表 5、从前序与中序遍历序列构造二叉树 6、 从中序与后序遍历序列构造二叉树 7、二叉树的前序遍历(非递归实现) 8、二叉树的中序遍历(…...

【antd之tabs踩坑篇】Tabs有items时切换不起作用
<TabsdefaultActiveKey"1"tabPosition{mode}style{{ height: 220 }}items{new Array(30).fill(null).map((_, i) > {const id String(i);return {label: Tab-${id},key: id,disabled: i 28,children: Content of tab ${id},};})}/>官网上如果tabs有很多it…...
简单模拟livedata数据倒灌
简单模拟livedata数据倒灌 数据倒灌,就是将旧的或只展示一次的数据再次展现出来。 livedata内部通过版本号更新可见视图数据,而在view在活跃与不活跃之间反复横跳时,livedata也会通知数据。 class MainActivity : AppCompatActivity() {pri…...

python爬虫-加速乐cookie混淆解析实例小记
注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!! 第一步:抓包工具第一次请求页面,得到响应。本次我使用的fiddle进行抓包&#…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...