【C#学习笔记】值类型(1)

news2024/12/23 8:44:39

在这里插入图片描述

虽然拥有编程基础的人可以很快地上手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是一个跨语言开发的规范它定义了用于跨平台编译的中间语言ILIL 代码和资源(如位图和字符串)存储在扩展名通常为 .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、short、int、long
这些都是很基础的,可以看官方文档,其中特殊的类型是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=1System.Int32 a=1是一致的。
在为整数赋值时可以使用十进制,十六进制和二进制,十进制就是正常的数字,十六进制以0X开头,二进制以0B开头。我们在赋值时使用十进制也可以以_作为分隔符,例如int a=3000int 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,  // 0
    Monday    = 0b_0000_0001,  // 1
    Tuesday   = 0b_0000_0010,  // 2
    Wednesday = 0b_0000_0100,  // 4
    Thursday  = 0b_0000_1000,  // 8
    Friday    = 0b_0001_0000,  // 16
    Saturday  = 0b_0010_0000,  // 32
    Sunday    = 0b_0100_0000,  // 64
    Weekend   = Saturday | Sunday
}
public class FlagsEnumExample
{
    public static void Main()
    {
        Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;
        Console.WriteLine(meetingDays);
        // Output:
        // Monday, Wednesday, Friday

        Days workingFromHomeDays = Days.Thursday | Days.Friday;
        Console.WriteLine($"Join a meeting by phone on {meetingDays & workingFromHomeDays}");
        // Output:
        // Join a meeting by phone on Friday

        bool isMeetingOnTuesday = (meetingDays & Days.Tuesday) == Days.Tuesday;
        Console.WriteLine($"Is there a meeting on Tuesday: {isMeetingOnTuesday}");
        // Output:
        // Is there a meeting on Tuesday: False

        var 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()
 */

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

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

相关文章

分库分表之基于Shardingjdbc+docker+mysql主从架构实现读写分离 (三)

本篇主要说明: 1. 因为这个mysql版本是8.0,所以当其中一台mysql节点挂掉之后,主从同步,甚至双向数据同步都失效了,所以本篇主要记录下当其中的节点挂掉之后如何再次生效。另外推荐大家使用mysql5.7的版本,这…

3-ASCII-座位渲染-二维码

一 ASCII码 1 概念 ascii码是一种计算机信息交换标准,在这个表里面制定了 128个数字跟128个字符的对应关系 我们只关注字母跟数字的对应关系 2 ASCII码转字符 let str String.fromCharCode(数字)二 js对象跟查询字符串互转 a js对象转查询字符串 //创建一个对象 let obj …

新SDK平台下载开源全志D1-H/D1s的SDK

获取SDK SDK 使用 Repo 工具管理,拉取 SDK 需要配置安装 Repo 工具。 Repo is a tool built on top of Git. Repo helps manage many Git repositories, does the uploads to revision control systems, and automates parts of the development workflow. Repo is…

【Python】模块学习之matplotlib柱状图、饼状图、动态图及解决中文显示问题

目录 前言 安装 pip安装 安装包安装 柱状图 主要方法 参数说明 示例代码 效果图 解决中文显示问题 修改后的图片 饼状图 主要方法 示例代码 效果图 动态图 主要方法 动态图官方使用介绍 示例代码 颜色设置 内建颜色 字体设置 资料获取方法 前言 众所周…

WPF上位机6——文件操作、多线程、线程锁、Task异步编程

文件操作 文件夹操作 创建文件夹 磁盘信息 文件的读写 文件流 Thread多线程 带参数创建线程 Task多线程 创建方式1 第一种 第二种 第三种:线程池的方式 前台与后台线程 线程锁 Task异步编程 task任务取消 task返回值 async await异步 并行库Parallel

CEC2014:CEC2014测试函数及多种智能优化算法求解CEC2014对比

目录 一、CEC2014测试函数 二、多种智能优化算法求解CEC2014 2.1 本文参与求解CEC2014的智能优化算法 2.2 部分测试函数运行结果与收敛曲线 三、曲线标记代码(获得代码后可自行更改) 一、CEC2014测试函数 CEC2014测试集共有30个单目标测试函数&#xff0…

linux下docker安装、镜像下载、镜像基础操作、容器基础操作

目录 一、环境准备 1、开启虚拟化 2、关闭防火墙 3、yum仓库获取阿里源(清华、京东都可以) 4、确保能ping到外网 二、安装docker 1、yum安装docker 2、启动docker并设置开机自启 3、安装docker-ce阿里镜像加速器 三、docker基本操作 1、查看版…

如何在项目需求与技术方案未确定的情况下掌控上线时间?

需求不明确与技术方案未确定的挑战 在任何项目管理过程中,需求和技术方案是两个核心环节。理想情况下,我们希望在项目开始阶段就有清晰明确的需求和经过深思熟虑的技术方案。然而,现实中的项目管理往往并不如此理想。 项目需求的重要性 需求…

2023年全新版Java学习路线,精心整理【文中送书福利 】

小伙伴们大家好,这里是动力节点,我们从2009年开始一直在从事Java培训 到今年已经整14年了,虽然现在不缺培训机构,更不缺Java培训,但是像我们这么多年专注这一件事的应该也不多。我们只希望在“专业”两个字上面不断精…

Vue3 基础知识点汇总 自学笔记,记录难点 和 新知识点

1.vue3 基础 1.1vue3基础及创建 npm init vue@latest1.2.熟悉项目目录及关键文字 1.3 组合式API-setup 1.4.组合式 API reactive 和ref 函数 (都是为了生成响应式数据) 1.5.组合式API-computed 计算属性函数 1.6.watch 函数 1.7.组合式API-生命周期函数 1.8.组合式 API-父子…

Spring之事务实现方式及原理

目录 Spring事务简介 Spring支持事务管理的两种方式 编程式事务控制 声明式事务管理 Spring事务角色 未开启事务之前 开启Spring的事务管理后 事务配置 事务传播行为 事务传播行为的可选值 Spring事务简介 事务作用:在数据层保障一系列的数据库操作同成功…

Python之pyinstaller打包exe填坑总结

一、起因 编写了一个提取图片中文字的python脚本,想传给同事使用,但是同事电脑上没有任何python环境,更没有安装python库,因此想到通过pyinstaller打包成exe程序传给同事使用,于是开始了不断地挖坑填坑之旅 import p…

Kafka-消费者组消费流程

消费者向kafka集群发送消费请求,消费者客户端默认每次从kafka集群拉取50M数据,放到缓冲队列中,消费者从缓冲队列中每次拉取500条数据进行消费。

Dockerfile构建SSHD镜像

Dockerfile构建SSHD镜像 基于Dockerfile制作镜像时首先需要建立工作目录,作为生成镜像的工作目录,然后分别创建并编写 Dockerfile文件、需要运行的脚本文件以及要复制到容器中的文件。 1、环境配置: [rootdocker ~]# iptables -F [rootdoc…

用python+PyQt5来编写一个定时关机窗口

一、界面展示 二、源码 import sys from PyQt5.QtWidgets import QDesktopWidget,QApplication, QWidget, QLabel, QVBoxLayout, QPushButton, QSpinBox import osclass AutoShutdownApp(QWidget):def __init__(self):super().__init__()self.setWindowTitle("自动关机应…

Aop监控所有Controller,包括void类型的response中的出参(工具类)

一、主要坐标 <!--aop--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifa…

saas堡垒机定义以及优势简单说明

工作中我们经常可以听到saas这个词语&#xff0c;但对于saas堡垒机相信还有很多人不了解。今天我们就来一起简单聊聊什么是saas堡垒机&#xff0c;saas堡垒机有哪些优势。 saas堡垒机定义 saas堡垒机顾名思义为一款SaaS化堡垒机产品&#xff0c;即一款SaaS运维审计安全系统。…

学习记录——EGE-UNet、R2AU-Net、PHNet、CFNet

EGE-UNet: an Efficient Group Enhanced UNet for skin lesion segmentation 上海交大 2023 MICCAI 基于 U-Net 进行魔改&#xff0c;用于解决医学图像&#xff08;尤其是皮肤病变&#xff09;分割中面临的问题。由于它是针对移动健康应用开发的&#xff0c;解决了当前许多模型…

硬件系统工程师宝典(35)-----SDRAM是如何“提速”的?

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。 上篇我们了解了FLASH可分为NOR FLASH和NAND FLASH&#xff0c;NOR FLASH一般用于代码运行及擦除或编程较少的场合&#xff0c;NAND FLASH用于擦除、…

【CSS】3D卡片效果

效果 index.html <!DOCTYPE html> <html><head><title> Document </title><link type"text/css" rel"styleSheet" href"index.css" /></head><body><div class"card"><img…