C# 常量 结构体 委托

Posted BoiledYakult

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 常量 结构体 委托相关的知识,希望对你有一定的参考价值。

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;

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

  • 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();就会报错。

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

[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();
    

C# 中的命名空间常量

【中文标题】C# 中的命名空间常量【英文标题】:Namespace constant in C# 【发布时间】:2011-02-18 14:05:06 【问题描述】:

有没有办法为整个命名空间定义一个常量,而不仅仅是在一个类中?例如:

namespace MyNamespace
    
    public const string MY_CONST = "Test";

    static class Program
    
    

给出如下编译错误:

预期的类、委托、枚举、接口或结构

【问题讨论】:

请注意,“常量变量”是矛盾的。变量各不相同,这就是为什么它们被称为“变量”。常量保持不变,这就是为什么它们被称为常量。变量是存储位置,常量是。它们完全不同;不可能有“常量变量”这样的东西。 【参考方案1】:

我相信这是不可能的。但是你可以创建一个只有常量的类。

public static class GlobalVar

    public const string MY_CONST = "Test";

然后像这样使用它

class Program

    static void Main()
    
        Console.WriteLine(GlobalVar.MY_CONST);
    

【讨论】:

+1 因为这是微软推荐的方法msdn.microsoft.com/en-us/library/bb397677.aspx 顺便说一句,实现这一点的另一种方法是使用您的 web.config 或 app.config(取决于您拥有哪一个)。 ***.com/a/4256864/105539【参考方案2】:

这是不可能的

来自MSDN:

const 关键字用于修改字段或局部变量的声明。

由于您只能在一个类中拥有一个字段或局部变量,这意味着您不能拥有一个全局const。 (即命名空间常量)

【讨论】:

【参考方案3】:

如果您也添加“使用静态”,您可以在其他类中使用常量:

using static MyNameSpace.MyGlobals;

namespace MyNameSpace 
    public static class MyGlobals
        public const bool SAVE_LOGSPACE = true;
        public static readonly DateTime BACKTEST_START_DATE = new DateTime(2019,03,01);
    

【讨论】:

【参考方案4】:

不,没有。将其放在静态类或枚举中。

【讨论】:

以上是关于C# 常量 结构体 委托的主要内容,如果未能解决你的问题,请参考以下文章

C#中类与结构体的区别

C# 中的命名空间常量

C#入门详解

你可能不知道的陷阱:C#委托和事件的困惑(转)

自己整理的c#语法和特性知识(c#1.0 -c#10)

自己整理的c#语法和特性知识(c#1.0 -c#10)