C# 常量 结构体 委托

常量

const double PI = 3.1415926;

常量名命名一般使用大写字母

枚举类型

开发一个游戏,游戏角色有法师(Mage)、射手(Archer)、刺客(Assassin)、坦克(Tank)、铺助(Support)、战士(Warrior),等不同类型。

❓如何存储游戏角色

  • 使用int类型 :创建一套规则,提前为各个类型角色绑定一个数字标识
  • 使用枚举类型

什么是枚举类型?

枚举类型是一种特殊的值类型,可以在枚举类型中定义一组命名的数值常量。

如何声明枚举类型?

enum <enum_name>
{
	value1,
	value2,
	value3,
	...
	valuen
}

默认情况下,

  • 每个枚举成员对应的数值都是int类型的
  • 按照枚举成员的生命顺序,,自动按照0、1、2 ······ 进程常量赋值。

可以指定其他的整数类型代替默认类型,也可以显示指定每一位枚举成员的对应值:

public enum BorderSide : byte { Left = 1, Right, Top = 10, Bottom }

上面的开发场景利用枚举类型就可以这样来完成:

enum RoleType { Mage, Archer, Assassin, Tank, Support, Warrior }
static void Main(string[] args)
{
    RoleType Top = RoleType.Tank;
    Top = RoleType.Warrior;
}

image-20230502164650057

  • 枚举类型的实例可以与它对应的整数值相互显式转换

  • RoleType Top = RoleType.Tank;
    int i=(int)Top;	// 3
    
  • 也可以显式将一个枚举类型转换为另一个

  • 由于枚举类型可以和它对应的整数类型相互转换,因此枚举的真实值可能超出枚举类型成员的数值范围,在使用过程中需要考虑类型安全问题

结构体

我们日常使用的变量,一般都是某一个单一的信息,比如一个学生的信息:

age
name
grade
studylD

❓对于一个学生信息的话,我们怎么对这些信息进行一个整合呢?

  • 结构体

什么是结构体?

  • 结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。
  • struct 关键字用于创建结构体。

结构体的作用就是把某一类的变量进行整合,组成一个新的数据类型,相当于一个新的信息。

如何声明结构体?

struct <struct_name>
{
	访问权限 type typename
	访问权限 ype typename
}

关于学生信息,就可以这样来存储:

struct Studentinfo
{
    public int age;
    public string name;
    public int grade;
    public int studylD;
}

static void Main(string[] args)
{
    Studentinfo xiaoming = new Studentinfo();
    xiaoming.age = 10;
    xiaoming.grade = 1;
    xiaoming.name = "小明";
    xiaoming.studylD = 107963212;
    Console.ReadKey();
}

结构体的构造语义如下:

  • 结构体隐式包含一个无法重写的无参数构造器。此构造函数不允许删除和重定义,并且这个无参数的构造函数会一直存在,并不会因为定义了其他带参数的构造函数就消失,这一点和类不同。

    • 构造器的作用是初始化对象,构造器也就是构造函数,通俗的讲就是你在实例化结构体也就是创建结构体对象时是new Studentinfo()还是new Studentinfo(10,1,"小明",107963212)
    • 构造函数(C# 编程指南)
  • 定义结构体的构造器时,必须显式为每一个字段赋值。

结构体构造函数(简单概述)

结构类型都有一个预定义的,没有参数的构造函数,这点与类是一样的。

看这个场景:

struct A
{
    static A()
    {
        Console.WriteLine("I am A.");
    }
    public void Fun()
    {

    }
}
static void Main(string[] args)
{
    A a = new A();
    a.Fun(); //结构的实例成员被引用
    Console.ReadKey();
}

输出结果为:I am A.

当你把a.Fun();注释掉以后再次运行程序你会发现程序不会输出任何东西。

❓那么结构体的静态构造函数何时触发呢

答案是:结构体的实例成员被引用,结构体的静态成员被引用,结构体显式声明的构造函数被调用。

就上上面说的:结构体隐式包含一个无法重写的无参数构造器。此构造函数不允许删除和重定义,并且这个无参数的构造函数会一直存在,并不会因为定义了其他带参数的构造函数就消失,这一点和类不同。

我们拿类来做比较:

struct Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
    //Name()
    //{
    //    Console.WriteLine("无参构造函数");
    //}
}
class _Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
    public _Name()
    {
        Console.WriteLine("无参构造函数");
    }
}
static void Main(string[] args)
{
    Name name = new Name();
    name.firstName = "三";
    name.lastName = "张";
    Console.WriteLine(name.FullName());
    _Name name1 = new _Name();

    Console.ReadKey();
}

结构体Name中的Name()构造函数在取消注释后编译器会报错,但是当你将Name()改成带参的构造函数后编译器就不会提示错误了。这个时候,按照类的思路来讲,我们在创建结构体Name的对象时应该要完成结构体带参构造的所有字段的初始化,否则就会报错。也就是说我们在创建Name结构体对象时应该这样写:

Name name = new Name("三","张");

但是我们发现,我们写Name name = new Name();也是没问题的,之所以为问题就是因为结构体隐式包含一个无法重写的无参数构造器。

我们换到类里面,将无参的构造函数改为带参数的,此时_Name name1 = new _Name();就会报错。

image-20230502185228652

此外,我们还可以发现,类的无参构造函数在初始化对象的时候就会调用,而结构体的静态默认无参构造函数则不会,只有在上述三种情况中才会被调用。

image-20230502185720358

[C# 结构体](https://www.cnblogs.com/arxive/p/5799245.html)

实例构造函数(C# 编程指南)

C# 结构体(Struct)

结构体函数

struct Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
}
static void Main(string[] args)
{
    Name name = new Name();
    name.firstName = "三";
    name.lastName = "张";
    Console.WriteLine(name.FullName());
    Console.ReadKey();
}

小练习

定义一个Vector3的结构体(这个结构体可以用来表示坐标,可以表示向量),在里面定义一个Distance方法,用来取得一个向量的长度的。

冷知识:向量长度 可以百度 一个向量的长度等于他和他自己的内积的平方根

struct Vector3
{
    public double x; public double y; public double z;
    public double Distance()
    {
        return Math.Sqrt(z * z + x * x + y * y);
    }
}
static void Main(string[] args)
{
    Vector3 v1 = new Vector3();
    v1.x = 4;
    v1.y = 5;
    v1.z = 6;
    Console.WriteLine(v1.Distance());
    Console.ReadKey();
}

委托(简单概述)

委托delegate是一种存储函数引用的类型。

委托的定义指定了一个返回类型和一个参数列表。

定义了委托之后,就可以声明该委托类型的变量,接着就可以把一个返回类型跟参数列表跟委托一样的函数赋值给这个变量。

简单来讲,委托delegate是一种存储数引用的类型。委托的定义指定了一个返回类型和一个参数列表定义了委托之后,就可以声明该委托类型的变量,接着就可以把一个返回类型跟参数列表跟委托一样的丽数赋值给这个变量。

static double Multiply(double param1, double param2)   
{
    return param1 * param2;
}
static double Divide(double param1, double param2)
{
    return param1 / param2;
}
delegate double MyDelegate(double param1, double param2);
static void Main(string[] args)
{
    MyDelegate delegate1;
    delegate1 = Multiply;
    Console.WriteLine(delegate1(2,4));  // 8
    delegate1 = Divide;
    Console.WriteLine(delegate1(4,2));   // 2
    Console.ReadKey();
}

可以理解为定义声明一种特殊的函数,,只有个声明,没有具体的函数体内容,函数的类型是delegate,需要用同参数类型、数量以及同返回值的函数赋值给委托变量。

internal class Program
{
    delegate void OnDieDelegate();
    static void PLay(OnDieDelegate onDie)
    {
        Console.WriteLine("做任务");
        Console.WriteLine("玩家正在战斗");
        Console.WriteLine("死");
        if(onDie != null)
        {
            onDie();
        }
    }
    static void ShowDieUI()
    {
        Console.WriteLine("显示游戏死亡后的UI");
        Console.WriteLine("返回首页UI");
    }

    static void Main(string[] args)
    {
        PLay(ShowDieUI);
        PLay(null);
        Console.ReadKey();
    }
}

原文链接:https://www.cnblogs.com/BoiledYakult/archive/2023/05/02/17368258.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 常量 结构体 委托 - Python技术站

(0)
上一篇 2023年5月2日
下一篇 2023年5月2日

相关文章

  • c# 值类型实例构造器

    C#值类型实例构造器 在C#中,值类型是一种基本数据类型,如int、double、char、bool等等。与引用类型不同,值类型的实例被存储在堆栈中,而不是在堆中。C#值类型实例构造器是一种特殊的方法,在值类型实例被创建时,它会被自动调用。本文将详细讲解C#值类型实例构造器的用法和示例。 构造器的概念和特点 构造器是一种特殊的方法,它用于初始化一个类的实例。…

    C# 2023年5月15日
    00
  • C#异步编程之async/await详解

    C#异步编程之async/await详解 简介 异步编程是现代编程中不可避免的一部分,它允许我们编写高性能和更加流畅的应用。C#中的async/await关键字是一种优雅的方式来处理异步操作,这篇文章将着重详解这一特性。 async和await是什么? async是一个修饰符,用于修饰一个方法,表示这个方法是异步方法。 await是一个操作,用于让方法等待另…

    C# 2023年5月15日
    00
  • Unity Sockect实现画面实时传输案例原理解析

    下面给出详细讲解“Unity Sockect实现画面实时传输案例原理解析”的完整攻略。 简介 在很多应用场景中,我们需要将实时的图像或视频流传输到另一个终端,比如远程监控、视频会议、VR/AR等应用。而Unity Sockect实现画面实时传输正是一种可以实现这种需求的方法。 原理 服务端 在服务端,我们需要使用Socket来监听一个端口,等待客户端的连接。…

    C# 2023年6月3日
    00
  • .net中的Span类和Memory类介绍

    .NET中的Span类和Memory类介绍 在.NET中,Span类和Memory类是用于处理内存的重要类型。本攻略将介绍这两个类的基本概念、用法和示例。 Span类 Span类是一个结构体,用于表示一段连续的内存区域。它可以用于读取和写入内存,而无需进行复制或分配。Span类的定义如下: public ref struct Span<T> { …

    C# 2023年5月17日
    00
  • C#启动windows服务方法的相关问题分析

    下面是针对”C#启动windows服务方法的相关问题分析”的完整攻略: 1. 了解Windows服务启动方式 在进行C#编程启动Windows服务之前,需要先了解Windows服务启动的几种方式: 自动:随着系统启动而启动。 自动(延迟启动):在系统启动完成后,延迟几个时间单位后启动。 手动:需要手动启动。 禁用:无法启动。 具体启动方式可在控制面板中的“管…

    C# 2023年5月15日
    00
  • 浅谈C#在网络波动时防重复提交的方法

    浅谈C#在网络波动时防重复提交的方法 在Web开发中,防止重复提交是一个非常常见的问题。当网络波动或者用户重复点击提交按钮时,很容易导致重复提交。本文将介绍一些C#在防止重复提交方面的方法,希望能帮助大家解决这个问题。 方案1:使用Session来控制重复提交 在C#中,可以使用Session来控制重复提交。每次提交请求时,将表单提交的信息与Session中…

    C# 2023年6月2日
    00
  • .NET Core Web APi大文件分片上传研究实现

    .NET Core Web API大文件分片上传研究实现 在Web应用程序中,大文件上传是一项常见的任务。为了提高上传效率和稳定性,我们可以将大文件分成多个小文件进行上传。在本攻略中,我们将详细讲解如何使用.NET Core Web API实现大文件分片上传,并提供两个示例说明。 步骤一:前端实现 在前端,我们需要使用JavaScript将大文件分成多个小文…

    C# 2023年5月17日
    00
  • Jquery插件仿百度搜索关键字自动匹配功能

    Jquery插件仿百度搜索关键字自动匹配功能是一种常见的前端开发技术,可以提高用户体验。以下是使用Jquery插件实现仿百度搜索关键字自动匹配功能的完整攻略。 环境准备 在使用Jquery插件前,需要引入Jquery库和Jquery插件。可以使用以下命令来引入Jquery库和Jquery插件: <script src="https://cod…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部