c# 值类型

目录

    • 1、c#类型
    • 2、值类型
      • 2.1 结构体
      • 2.2 枚举

1、c#类型

类型(Type)又叫数据类型(Data Type)。
A data type is a homogeneous collection of values,effectively prensented,equipped with a set of operations which manipulate these values.

  • 数据类型是由相同类型的值组成的集合。比如int[]是整数的集合。
  • 数据类型配备有专门针对自己的值的一组运算操作,比如int类型的数据可以进行加法、减法、乘法、除法操作。深层的意思是,这一组操作是专门为这一种数据类型准备的,我们不能拿数据类型A的操作去对数据类型B进行操作。
  • 数据类型的“类型”二字包含有“型号”的意思,也就是说,一个数据类型代表着这种数据类型的值在内存中存储时需要占多少的内存,比如对于int来说,它可存储-2,147,483,648 到 2,147,483,647范围内的值,需要占4个字节。我们在存储数据时,应该选择合适的数据类型,比如我们想要存储100这个数据,如果使用int的话显得太浪费了,使用byte就够用了,byte只占一个字节;而如果我们想要存储256这个数据,使用byte就不行了,因为byte只能存储0~255的整数。所以说,大内存存储小尺寸的数据会导致浪费,小内存存储大尺寸的数据会导致丢失精度。举一个现实中的例子,有一个盒子,如果我们拿一个橡皮丢进去,空间完全足够而且还有很多空出来的空间没有得到利用,而如果我们拿一把椅子丢进去就不行了,这时候如果想强制丢进去,只能把椅子的一部分放进去,椅子就会被损坏了。
  • 数据类型会被有效地表示,包括存储在内存中的位置、占内存的大小、类型包含的成员(方法、字段、事件等)、类型所继承的基类型。
  • c#是一种强类型的语言,这意味着每个变量和常量都必须有一个明确的数据类型。这样编译器就能保证代码中执行的所有运算都是类型安全的。例如,如果定义了一个 int 类型的变量,则编译器允许在加法和减法运算中使用此变量, 如果尝试在一个 string 类型的变量上执行相同的运算,则编译器会产生错误。
// c#代码
int a = 10;
string str = "Hello, world!";
int b = a + str;//输出结果为:
//无法将类型“string”隐式转换为“int”
# python代码
a = 10
a = "Hello, world!"

c#类型分为值类型和引用类型,值类型有结构体和枚举,引用类型有类、接口、委托。

在这里插入图片描述

struct MyStruct  // 定义结构体
{}Type type = typeof(int); //使用typeof关键字获取int的类型
Console.WriteLine(type.BaseType); //打印int的基类型
Console.WriteLine(type.BaseType.BaseType); //打印int的基类型的基类型Console.WriteLine("---------");
type = typeof(MyStruct); //使用typeof关键字获取MyStruct的类型
Console.WriteLine(type.BaseType); //打印MyStruct的基类型
Console.WriteLine(type.BaseType.BaseType); //打印MyStruct的基类型的基类型//输出结果为:
//System.ValueType
//System.Object
//---------
//System.ValueType
//System.Object

2、值类型

值类型的变量存储数据,而引用类型的变量存储对实际数据的引用。详见引用变量与实例。

2.1 结构体

结构体和类很相似,结构体通常用来封装小型相关变量组。
与类相比,结构体有一些限制,例如它不能声明为抽象的或密封的,它也不能声明默认构造函数(没有参数的构造函数)和析构函数。结构体通常用于小型、不可变的数据结构,而类更适合用于需要更复杂行为的对象。
结构体在C#中是实现轻量级数据结构的强大工具,它在性能上通常优于类,因为它避免了垃圾回收的开销。然而,它也有一定的限制,比如不能被声明为可空的,并且当结构体包含引用类型字段时,可能会引入垃圾回收的开销。
结构体可以包含构造函数常量字段方法属性索引器运算符事件嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。

struct Student
{public int age;public int height;public double weight;public string name;
}

我们不能在结构体中初始化实例字段,可以在结构体中初始化静态字段以及常量。

struct Student 
{public static int avgAge = 10;  //可以在结构体中初始化静态字段public const int height = 100;  //可以在结构体中初始化常量public int age;  //不能在结构体中初始化实例字段
}

要想初始化实例字段,有两种方法:一是使用参数化构造函数,二是在声明结构后分别访问成员。

struct Student 
{public Student(int x){age = x;}//public static int avgAge = 10;public int age;
}Student stu = new Student(10);  //使用参数化构造函数初始化实例字段
Console.WriteLine(stu.age);
stu.age = 20;  //声明结构后访问实例字段
Console.WriteLine(stu.age);//输出结果为:
//10
//20

与类不同,结构的实例化可以使用new运算符,也可以不使用。如果使用的话,会创建该结构的对象,并调用构造函数,构造函数不传入参数的话,调用的是默认构造函数,默认构造函数会对结构体的成员进行初始化;如果不使用的话,就不会调用构造函数,在初始化所有字段之前,字段将保持未赋值状态且对象不可用。

struct Student 
{public int age;public int height;
}Student stu1; //不使用new创建对象
Student stu2 = new Student();  //使用new创建对象,并调用构造函数
struct Student 
{public int age;public int height;
}Student stu1; //不使用new创建对象
Console.WriteLine(stu1.age);//输出结果为:
//使用了可能未赋值的字段"age"

所以正确的做法应该是:

struct Student 
{public int age;public int height;
}Student stu1; 
stu1.age = 10;
stu1.height = 130;
Console.WriteLine(stu1.age);
Console.WriteLine(stu1.height);
struct Student 
{public int age;public int height;
}Student stu2 = new Student(); 
Console.WriteLine(stu1.age);
Console.WriteLine(stu1.height);

2.2 枚举

枚举类型用enum关键字进行声明,它是一种由一组称为枚举数列表的命名常量组成的独特类型。
通常情况下,最好是在命名空间内直接定义枚举,以便该命名空间中的所有类都能够同样方便地访问它。 但是,还可以将枚举嵌套在类或结构中。
默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1。

namespace ConsoleApp1
{enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun };class Program{static void Main(string[] args){Console.WriteLine((int)Days.Mon);Console.WriteLine((int)Days.Tue);Console.WriteLine((int)Days.Wed);}}
}//输出结果为:
//0
//1
//2

当然,也可以强制元素序列从1开始。

namespace ConsoleApp1
{enum Days { Mon=1, Tue, Wed, Thu, Fri, Sat, Sun };class Program{static void Main(string[] args){Console.WriteLine((int)Days.Mon);Console.WriteLine((int)Days.Tue);Console.WriteLine((int)Days.Wed);}}
}//输出结果为:
//1
//2
//3

枚举类型的默认基础类型是int,所以,上述代码中定义枚举类型变量的完整表达为:

enum Days:int { Mon=1, Tue, Wed, Thu, Fri, Sat, Sun };

枚举类型变量可赋以基础类型范围内的任何值,准许使用的枚举类型有 byte、 sbyte、 short、 ushort、 int、 uint、 long 或 ulong。

namespace ConsoleApp1
{enum Days:byte { Mon=1, Tue=2, Wed=10, Thu=20, Fri=30, Sat=100, Sun=255 };class Program{static void Main(string[] args){Console.WriteLine((byte)Days.Mon);Console.WriteLine((byte)Days.Tue);Console.WriteLine((byte)Days.Wed);Console.WriteLine((byte)Days.Thu);Console.WriteLine((byte)Days.Fri);Console.WriteLine((byte)Days.Sat);Console.WriteLine((byte)Days.Sun);}}
}//输出结果为:
//1
//2
//10
//20
//30
//100
//255

在switch语句中使用枚举值。

namespace ConsoleApp1
{enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun };class Program{static void Main(string[] args){Days day = (Days)1;switch (day){case Days.Mon:Console.WriteLine("Today is Mon");break;case Days.Tue:Console.WriteLine("Today is Tue");break;case Days.Wed:Console.WriteLine("Today is Wed");break;case Days.Thu:Console.WriteLine("Today is Thu");break;case Days.Fri:Console.WriteLine("Today is Fri");break;case Days.Sat:Console.WriteLine("Today is Sat");break;case Days.Sun:Console.WriteLine("Today is Sun");break;}}}
}

使用枚举类型的好处:

  • 明确变量可以存储的值。
enum Days:byte { Mon=1, Tue=2, Wed=10, Thu=20, Fri=30, Sat=100, Sun=255 };
Days day = Days.Mon;

在这个程序中,一个星期只能包含从星期一到星期日的7天,所以只能取枚举中的值。

我们可以使用扩展方法为枚举类型添加功能。

namespace ConsoleApp1
{// 在非泛型静态类中定义扩展方法public static class Extensions{        public static Grades minPassing = Grades.D;// this关键字在方法定义中用于指定这是一个扩展方法//this关键字后面跟着的是类型参数,表示这个扩展方法可以被任何Grade类型的实例调用public static bool Passing(this Grades grade)  {return grade >= minPassing;}}public enum Grades { F = 0, D=1, C=2, B=3, A=4 };class Program{       static void Main(string[] args){Grades g1 = Grades.D;Grades g2 = Grades.F;Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");Extensions.minPassing = Grades.C;Console.WriteLine("\r\nRaising the bar!\r\n");Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");}}}
}/* 输出结果为:First is a passing grade.Second is not a passing grade.Raising the bar!First is not a passing grade.Second is not a passing grade.*/

实际上,通过枚举类型实例对扩展方法的调用,等效于调用普通非扩展方法的方式。也就是说,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异。

Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");
// 等效于
Console.WriteLine("First {0} a passing grade.", Extensions.Passing(g1) ? "is" : "is not");
Console.WriteLine("First {0} a passing grade.", Extensions.Passing(g2) ? "is" : "is not");

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

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

相关文章

【压力测试】如何确定系统最大并发用户数?

一、明确测试目的与了解需求 明确测试目的:首先需要明确测试的目的,即为什么要确定系统的最大并发用户数。这通常与业务需求、系统预期的最大用户负载以及系统的稳定性要求相关。 了解业务需求:深入了解系统的业务特性,包括用户行…

【玉米叶部病害识别】Python+深度学习+人工智能+图像识别+CNN卷积神经网络算法+TensorFlow

一、介绍 玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集(‘矮花叶病’, ‘健康’, ‘灰斑病一般’, ‘灰斑病严重’, ‘锈病一般’, ‘锈病严重’, ‘叶斑病一般’, ‘叶斑病严重’&#x…

PAT甲级-1048 Find Coins

题目 题目大意 给出硬币的个数n和要付费的钱m&#xff0c;接下来给出每个硬币的面值。要求从这些硬币中找到两个硬币v1, v2&#xff0c;使得v1 v2 m&#xff0c;且v1 < v2&#xff0c;输出v1 v2。如果不能找到这两个硬币&#xff0c;输出No Solution。 思路 刚开始用的…

算法练习:LCR 179. 查找总价格为目标值的两个商品

题目链接&#xff1a;LCR 179. 查找总价格为目标值的两个商品 利用双指针位于数值两端来进行控制&#xff0c;定义sum来记录两指针分别对应的值的和&#xff0c; 这里有个重要的点就是该数组是升序&#xff0c;所以&#xff1a; 当sum > target时&#xff0c;end--&#x…

构建数据湖仓的开源技术栈有哪些

湖仓一体架构是一种新兴的数据管理方式&#xff0c;它融合了数据湖和数据仓库的优势&#xff0c;提供了统一的数据存储、事务支持、数据治理、实时与批处理能力以及弹性和可扩展性。在开源领域&#xff0c;湖仓一体技术栈的选择非常关键&#xff0c;因为它直接影响到系统的灵活…

每日OJ题_牛客_排序子序列_模拟_C++_Java

目录 牛客_排序子序列_模拟 题目解析 C代码 Java代码 牛客_排序子序列_模拟 排序子序列_牛客笔试题_牛客网 (nowcoder.com) 描述&#xff1a; 牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数…

电脑软件:推荐一款免费且实用的电脑开关机小工具

目录 一、软件简介 二、软件功能 三、软件特点 四、使用说明 五、软件下载 今天给大家推荐一款免费且实用的电脑开关机小工具KShutdown&#xff0c;有需要的朋友可以下载试一下&#xff01; 一、软件简介 KShutdown是一款精巧且实用的定时自动关机小工具&#xff0c;对于…

网关如何传递信息给微服务

前情回顾 上篇我们已经完成了网关对所有微服务请求的拦截以及JWT的登录校验。 客户端和微服务之间的桥梁--网关&#xff08;身份校验&#xff09;https://mp.csdn.net/mp_blog/creation/editor/143425484 问题引入 现在的问题是在一些微服务业务中&#xff0c;需要用到用户…

BGP路由优选+EVPN

BGP 的路由优选规则是一套多步决策链&#xff0c;用来确定在多个可行路由中选择最优的路由。BGP 是一种路径向量协议&#xff0c;通过这些优选规则&#xff0c;网络管理员可以控制数据流量的流向&#xff0c;确保网络的稳定性和效率。下面以一个实例来详细说明 BGP 的优选规则及…

Vue3图片懒加载(vue3-lazyload)

Vue2图片懒加载 参考文档&#xff1a;vue3-lazyload 效果如下图&#xff1a;vue3-lazyload0.3.8 在线预览 安装 npm install vue3-lazyload # or yarn add vue3-lazyload # or pnpm add vue3-lazyload引入并注册 import { createApp } from vue import VueLazyLoad from v…

Hudi Upsert原理

1. 前言 如果要深入了解Apache Hudi技术的应用或是性能调优&#xff0c;那么明白源码中的原理对我们会有很大的帮助。Upsert是Apache Hudi的核心功能之一&#xff0c;主要完成增量数据在HDFS/对象存储上的修改&#xff0c;并可以支持事务。而在Hive中修改数据需要重新分区或重…

ctfshow web入门文件上传总结

1.web151 前端验证 前端验证&#xff0c;修改html代码&#xff0c;上传还有一句话木马的php文件,之后用蚁剑连接即可找到flag <?php eval($_POST[1])?>2.web152 后端验证&#xff0c;修改mime类型(content-type) burp抓包&#xff0c;修改content-type为image/png …

基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)

&#x1f388;系统亮点&#xff1a;协同过滤算法、节流算法、支付宝沙盒支付、图形化分析、实时聊天&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk1…

手把手写Linux第一个小程序 - 进度条(5种版本)

本专栏内容为&#xff1a;Linux学习专栏&#xff0c;分为系统和网络两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握Linux。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;linux &#x1f69a;代码仓库&#xff1a;小小unicorn的代…

dhcp池没有空闲ip导致手机无法获得ip

得到用户反馈&#xff0c;一个高速项目部的wifi无法接入&#xff0c;让排查原因。 反馈有的手机能接入&#xff0c;有的接入不了。查看ac界面发现有个终端获得的ip是169.254.xxx.xxx。 ip地址是169.254.96.17显然是手机打开wlan开关后&#xff0c;鉴权通过后dhcp过程&#xff0…

《高频电子线路》—— 振荡器稳定性问题

文章内容来源于【中国大学MOOC 华中科技大学通信&#xff08;高频&#xff09;电子线路精品公开课】&#xff0c;此篇文章仅作为笔记分享。 振荡器稳定性问题 频率准确度 & 频率稳定度 希望频率稳定度越小越好。 频率稳定度分类 影响振荡频率稳定度的参数 振荡频率是和电…

HTMLCSS: 打造跳一跳加载器,点燃用户等待热情

效果演示 这段 HTML 代码创建了一个简单的网页&#xff0c;其中包含一个动画效果&#xff0c;用来模拟一个加载器loading HTML <div class"loader"></div>div创建了一个动画效果的加载器 CSS html, body {width: 100vw;height: 100vh;display: flex…

Nginx 的 Http 模块介绍(上)

Nginx 的 Http 模块介绍&#xff08;上&#xff09; 1. http 请求 11 个处理阶段介绍 Nginx 将一个 Http 请求分成多个阶段&#xff0c;以模块为单位进行处理。其将 Http请求的处理过程分成了 11 个阶段&#xff0c;各个阶段可以包含任意多个 Http 的模块并以流水线的方式处理…

网络:ARP的具体过程和ARP欺骗

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言ARP具体过程ARP欺骗原理总结 前言 本文仅作为ARP具体过程和ARP欺骗的知识总结 硬件类型 &#xff1a;指定发送和接受ARP包的硬件类型&am…

[0260].第25节:锁的不同角度分类

MySQL学习大纲 我的数据库学习大纲 从不同维度对锁的分类&#xff1a; 1.对数据操作的类型划分:读锁和写锁 1.1.读锁 与 写锁概述&#xff1a; 1.对于数据库中并发事务的读-读情况并不会引起什么问题。对于写-写、读-写或写-读这些情况可能会引起一些问题&#xff0c;需要使用…