C# 常量 结构体 委托
Posted BoiledYakult
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
就会报错。
此外,我们还可以发现,类的无参构造函数在初始化对象的时候就会调用,而结构体的静态默认无参构造函数则不会,只有在上述三种情况中才会被调用。
结构体函数
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# 常量 结构体 委托的主要内容,如果未能解决你的问题,请参考以下文章