每当创建类或结构的实例时,将会调用其构造函数。 类或结构可能具有采用不同参数的多个构造函数。 使用构造函数,程序员能够设置默认值、限制实例化,并编写灵活易读的代码
如果静态构造函数尚未运行,静态构造函数会在任何实例构造函数操作执行之前运行
构造函数 函数名和类名一样,构造对象并且初始化的作用
构造函数语法
构造函数是一种方法,其名称与其类型的名称相同。 其方法签名仅包含可选访问修饰符、方法名称和其参数列表;它不包含返回类型。 以下示例演示一个名为 Person
的类的构造函数。
public class Person
{
private string last;
private string first;
public Person(string lastName, string firstName)
{
last = lastName;
first = firstName;
}
// Remaining implementation of Person class.
}
如果某个构造函数可以作为单个语句实现,则可以使用表达式主体定义。 以下示例定义 Location
类,其构造函数具有一个名为“name”的字符串参数。 表达式主体定义给 locationName
字段分配参数。
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
静态构造函数
前面的示例具有所有已展示的实例构造函数,这些构造函数创建一个新对象。 类或结构也可以具有静态构造函数,该静态构造函数初始化类型的静态成员。 静态构造函数是无参数构造函数。 如果未提供静态构造函数来初始化静态字段,C# 编译器会将静态字段初始化为其默认值,如 C# 类型的默认值中所列。
以下示例使用静态构造函数来初始化静态字段。
public class Adult : Person
{
private static int minimumAge;
public Adult(string lastName, string firstName) : base(lastName, firstName)
{ }
static Adult()
{
minimumAge = 18;
}
// Remaining implementation of Adult class.
}
也可以通过表达式主体定义来定义静态构造函数
public class Child : Person
{
private static int maximumAge;
public Child(string lastName, string firstName) : base(lastName, firstName)
{ }
static Child() => maximumAge = 18;
// Remaining implementation of Child class.
}
析构函数 ~
主要作用:在于对象销毁前系统会自动调用,进行一些清理工作 收回创建对象时申请的空间
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
注: 先置为空
p1=null;//先置为空在 collec
GC.Collect();//只有设置为空之后 cg垃圾回收机制才会检测为空的字段 并且对空字段进行释放所占的内存
静态属性和非静态属性
静态属性(static) 类名 属性名调用
非静态属性(没static);对象属性 1先创建对象 属性
class Sb
{
public static int num { get; set; }
public int count { get; set; }
//静态的只能访问静态的
public static void F1()
{
num++;
}
//非静态可以访问所有的类生成
public void F2()
{
count++;
num++;
}
public int F3()
{
return num;
}
}
Sb.num ++;
Sb.num++;
Sb.num++;
Console.WriteLine(Sb.num);
Sb s1 = new Sb();
s1.count++;
Console.WriteLine(s1.F3()); //3 所有的对象都会共享静态属性
Console.WriteLine(s1.count+"---"); //0非静态的属性每个对象都是互不相关的 没有任何练习
Sb s2 = new Sb();
Console.WriteLine(s2.F3()); //3
静态方法和非静态方法
静态方法(static):类名 方法名();静态方法里面只能访问静态成员
非静态方法(没static)对象方法名 非静态方法中可以访问所有的成员
class People
{
//类包含静态成员和非静态成员
//属性和方法 不叫static 属于 属于非静态属性和非静态方法 每一个对象都有一份 对象 属性使用方式去使用
//属性和方法 添加了static属于静态属性和静态方法 存储类上的 所有的对象共享一个成员
public int Age { get; set; } //非静态属性 对象 属性 使用方式使用
public static int Num { get; set; } //静态属性 类名 属性进行使用
//非静态方法 对象 类名() 可以访问所有的类成员 包括静态属性和非静态属性 静态方法和非静态方法
public void Test()
{
Console.WriteLine("年龄是" + Age + "数量" + Num);
Test2();//可以调用静态方法
}
//静态方法使用方式 类名 方法名() 只能访问静态成员 访问静态属性和静态方法
public static void Test2()
{
Console.WriteLine("我是静态方法");
// Test() 不能调用非静态属性和方法
}
}
类包含静态成员和非静态成员
属性和方法 不叫static 属于 属于非静态属性和非静态方法 每一个对象都有一份 对象 属性使用方式去使用
属性和方法 添加了static属于静态属性和静态方法 存储类上的 所有的对象共享一个成员
People.Num = 10;
People p1 = new People();
p1.Age = 10;
People p2 = new People();
p2.Age = 10;
p1.Age += 1;
Console.WriteLine(p1.Age);
p1.Test();
People.Test2();
密封类
密封类是一种特殊的类,它使用 sealed 关键字进行标记,以防止其他类从它继承。密封类的主要目的是限制类的继承链,确保类的设计和实现不被进一步扩展或修改
密封类的定义和特性
public sealed class MyClass
{
}
一旦类被声明为密封的,它就不能被其他任何类继承。这意味着密封类不能作为基类,也不能是抽象类。密封类中的所有成员都是最终的,不能被派生类重写或修改
密封类的使用场景
密封类在 C# 中的一个常见用途是提供一种确保类的稳定性和安全性的方法。例如,当开发者希望创建一个具有特定功能的类,并且不希望其他开发者通过继承来改变或扩展这些功能时,可以使用密封类。此外,密封类可以提供一些性能优化,因为编译器知道这些类不会有任何派生类,因此可以进行一些特定的优化处理。
密封类与密封方法的区别
密封类与密封方法是两个不同的概念。密封方法是指在派生类中重写的基类虚方法,使用 sealed 关键字标记,以防止进一步的重写。而密封类则是指整个类都被密封,不允许任何形式的继承
// 声明一个密封类
public sealed class SealedClass
{
public int Add(int a, int b)
{
return a + b;
}
}
// 尝试从密封类继承将导致编译错误
// public class DerivedClass : SealedClass
// {
// // 错误:无法从密封类型继承
// }
密封类是 C# 中一个重要的概念,它提供了一种机制来防止类的继承,确保类的设计意图得到保护。通过使用密封类,开发者可以创建稳定且不可变的类结构,同时可能获得一些性能上的优势。密封类的使用应当谨慎,确保它符合设计目标和需求