成员变量------特征
成员方法------行为
构造函数
无参构造函数
类中是允许自己声明无参构造函数的,而结构体是不允许的
class Person
{
public string name;
public int age;
//无参构造函数
public Person()
{
name = "唐老狮";
age = 18;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("构造函数和析构函数");
Person p = new Person();//调用无参构造函数
Console.WriteLine(p.age);
}
}
重载构造函数
public Person(int age)
{
//this代表当前调用该函数的对象自己
//当传入参数名字与成员变量名字相同时,需要用this区分哪个参数是对象参数
this.age = age;
}
public Person(string name)
{
this.name = name;
}
public Person(int age, string name)
{
this.age = age;
this.name = name;
}
特殊构造函数
this括号里面是哪个参数,那就先执行哪个构造函数,再来执行冒号前面的构造参数
//这里如果这么声明,this()会先默认调用无参构造函数
public Person(int age, string name): this()
{
Console.WriteLine("Person两个参数构造函数调用");
}
//无参构造函数
public Person()
{
name = "唐老狮";
age = 18;
}
//这里如果这么声明,this(name)会先默认调用传参(name)的构造函数
public Person(int age, string name): this()
{
Console.WriteLine("Person两个参数构造函数调用");
}
public Person(string name)
{
this.name = name;
}
成员属性
用于保护成员变量,为成员属性的获取和赋值添加逻辑处理------解决3p局限性问题(private/public/protected)
这里的使用核心是get return一个对应变量 ,set 使用一个value赋值。
cs
class Person
{
private string _name; // 私有字段
public string Name // 公共属性
{
get { return _name; }
set { _name = value; }
}
// 或者使用自动实现属性(更简洁)
// public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "唐老狮";
}
}
简单说说这里如何处理3p局限性
cs
1、首先这里是public访问权限,里面不能get和set都是private
2、如果get 是private,就不允许外部获取;如果set 是private,就不允许外部修改
public int Money
{
private get
{
// 解密处理
return money - 5;
}
set
{
// 加密处理
money = value + 5;
}
}
成员属性加密处理
这里可能还是会用函数进行加密,防止value数值直接被拆包然后修改?
cs
public int Money
{
get
{
// 解密处理
return money - 5;
}
set
{
// 加密处理
money = value + 5;
}
}
自动属性
如果类中有一个特征是:只希望外部获取而不希望外部修改的
cs
public float Height
{
get;
private set;
}
静态成员
从如下代码你可以发现,你使用静态类并没有实例化一个类作为对象使用,而是直接使用类名进行调用了
特点:不用new一个,可以直接类名点出来
cs
class MyCalss
{
public static float PI = 3.1415926f;
public static float AreaOfCircle (float r)
{
return Person.PI * r * r;
}
}
float areaCircle = MyCalss.AreaOfCircle(7);
为什么可以直接使用类名就能用?
**静态成员的特点 :**程序开始运行时 就会分配内存空间------这也注定了静态成员具有唯一性(即任何修改就是修改其本身,任何地方都是使用它内存中的内容,修改也是修改其内存内容)
而实例化也是通过new分配内存空间
**特点2:**静态成员与程序同生共死
特点3 :静态函数中不能使用非静态成员(生命周期的差异)
cs
class Test
{
//静态成员变量
static public float PI = 3.1415926f;
//成员变量
public int testInt = 100;
//静态成员方法
public static float CalcCircle(float r)
{
return PI * r * r;
如果这里直接使用testInt会报错,因为Test类还未被实例化
正确方法:
Test t=new Test();
Console.WriteLine(t.testInt);
}
//成员方法
public void TestFun()
{
Console.WriteLine("123");
}
}
特点4:非静态函数可以使用静态成员
因为这是生命周期的缘故,静态成员从程序一开始就出现了,成员可以直接被函数使用
静态变量的作用
静态变量:
1.常用唯一变量的申明
2.方便别人获取的对象申明
如单例模式
静态方法:
1.常用的唯一的方法申明
比如 相同规则的数学计算相关函数
静态类
使用static关键字修饰的类,只能包含静态成员
不能被实例化 具有唯一性 适合用作工具类(计算公式 等)
cs
static class Tools
{
// 静态成员变量
public static int testIndex = 0;
// 静态方法
public static void TestFun()
{
// 方法体为空
}
// 静态属性(带 get/set)
public static int TestIndex
{
get;
set;
}
}
静态类的静态构造函数
使用static关键字修饰的构造函数,无访问修饰符 无参数
**什么时候被调用:**自动调用一次,只要是第一次使用静态构造函数中的静态成员,就会自动调用
作用: 主要用于初始化静态成员。
静态类和普通类中的静态构造函数功能一样,调用类时都会优先执行静态构造函数进行初始化
与构造函数(针对实例对象)不同的是,静态构造函数(针对类)只执行一次 ,并且是在第一个实例对象创建前被调用 ,所以它可以用于那些只需要执行一次的操作;而且它不允许有public等修饰符,由程序自动调用,不能被外界调用。
cs
static class StaticClass
{
public static int testInt = 100;
public static int testInt2 = 100;
static StaticClass()
{
Console.WriteLine("静态构造函数");
testInt = 200;
testInt2 = 300;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("静态类和静态构造函数!");
Console.WriteLine(StaticClass.testInt);
Console.WriteLine(StaticClass.testInt2);
Console.WriteLine(StaticClass.testInt); // 重复输出 testInt
}
}
普通类的静态构造函数
cs
class Test
{
public static int testInt = 200;
static Test()
{
Console.WriteLine("静态构造");
}
public Test()
{
Console.WriteLine("普通构造");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Test.testInt);
Test t = new Test();
Test t2 = new Test();
}
}

意味着使用这个普通类中的成员,也就会自动调用这个类中的静态构造函数
静态构造函数的误解点
之前这里我如果把 public static int testInt = 200;变为普通成员变量public int testInt = 200
Console.WriteLine(Test.testInt);会报错------我误以为是静态构造函数必须要搭配静态成员
cs
class Test
{
public static int testInt = 200;
public int testInt2 = 300;
static Test()
{
Console.WriteLine("静态构造");
}
public Test()
{
Console.WriteLine("普通构造");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Test.testInt);
Test t = new Test();
Test t2 = new Test();
}
}
是因为这里使用了静态成员的调用方式------直接使用类名+静态成员变量:Test.testInt
但此时这里testInt已经不是静态成员了,不可使用此方式,如果要使用只能使用普通成员变量的使用方式
cs
class Program
{
static void Main(string[] args)
{
Test t = new Test();
Test t2 = new Test();
Console.WriteLine(t.testInt); // ✅ 正确:通过实例访问
Console.WriteLine(t2.testInt2); // ✅
}
}
扩展方法
为现有非静态变量类型添加新方法
|-------------------------------------------------------|
| 1.必须把扩展方法定义在静态类中,每个扩展方法也必须声明为静态的 |
| 2.所有扩展方法必须要使用this关键字对第一个参数进行修饰(第一个参数value即调用该扩展方法的对象) |
cs
static class Tools
{
// 为 int 拓展了一个成员方法
// 成员方法是需要实例化对象后才能使用的
// value 代表使用该方法的实例化对象
public static void SpeakValue(this int value)
{
Console.WriteLine("唐老师为int拓展的方法" + value);
}
}
class Program
{
static void Main(string[] args)
{
int i = 10;
int类型的 实例化对象i调用了 int 类型扩展的新方法SpeakValue
i.SpeakValue();
}
}
这里int类是系统自带的,系统本身未提供SpeakValue方法给int类型,这里使用扩展方法相当于是int类型扩展了新方法SpeakValue
为自定义类扩展方法
这里就是给Test类(自定义类)扩展了一个方法,然后一个t(Test类实例化对象)调用此方法
cs
static class Tools
{
// 为 int 拓展了一个成员方法
// 成员方法是需要实例化对象后才能使用的
// value 代表使用该方法的实例化对象
public static void Fun3(this Test t)
{
Console.WriteLine("为test拓展的方法");
}
}
static void Main(string[] args)
{
Test t = new Test();
t.Fun3();
}
class Test
{
public int i = 10;
public void Fun1()
{
Console.WriteLine("123");
}
public void Fun2()
{
Console.WriteLine("456");
}
}
当扩展方法和类中自带方法重名时
这里优先输出结果是类中自带方法。
cs
using System;
internal static class Tools
{
// 为 Test 拓展一个方法(扩展方法必须定义在 static 类中)
public static void Fun2(this Test t)
{
Console.WriteLine("为test拓展的方法");
}
}
internal static class Program
{
private static void Main(string[] args)
{
var t = new Test();
t.Fun2();
}
}
internal class Test
{
public void Fun2()
{
Console.WriteLine("456");
}
}
重载运算符
让自定义结构体和自定义类使用运算符
基本语法:
cs
public static 返回类型 operator 运算符(参数列表)
operator + 并不是一个"类名",而是一个 C# 中用于定义运算符重载的特殊语法。
它的作用是:告诉编译器,当两个 Point 对象使用 + 运算符时,应该执行这个方法里的逻辑。
算数运算符
cs
class Point
{
public int x;
public int y;
public static Point operator +(Point p1, Point p2)
{
Point p = new Point();
p.x = p1.x + p2.x;
p.y = p1.y + p2.y;
return p;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("运算符重载");
Point p = new Point();
p.x = 1;
p.y = 1;
Point p2 = new Point();
p2.x = 2;
p2.y = 2;
Point p3 = p + p2;
}
}
重载的表现
cs
class Point
{
public int x;
public int y;
public static Point operator +(Point p1, Point p2)
{
..................
}
public static Point operator +(Point p1, int value)
{
Point p = new Point();
p.x = p1.x + value;
p.y = p1.y + value;
return p;
}
class Program
{
static void Main(string[] args)
{
......//沿用上方案例p1,p2
Point p4 = p2 + 3
}
}
}
其他运算符
cs
//还有条件运算符以及逻辑运算符
public static bool operator !(Point p1)
{
return false;
}
public static bool operator >(Point p1, Point p2)
{
return false;
}