简介
主要记录的是面向对象编程中,类的字段,属性,构造器的使用,注意事项
面向对象编程
访问权限修饰符
- public :完全访问权限
- internal:仅可以才程序集内访问,或友元函数访问
- private:仅可以在包含类型中访问
- protected:仅可以在包含类型或子类中访问
- protected internal:protected 和 internal 可访问性的并集
程序集 : 就是一次打包的集合,包含多个资源文件
添加程序集特性,才能让其他友元程序集访问
[assembly:InternalsVisibleTo("Friend")]
//如果友元程序集有强名称,必须指定完整的160字节公钥
[assembly:InternalsVisibleTo("StrongFriend,PublicKey=xxx....")]
//这里的公钥是打包的时候设置的,在vs中也可以点击右键项目,在属性中设置
类
- 类的修饰符
有 public ,internal , abstract ,sealed , static , unsafe , partial,默认是internal
- 类名后缀
可以添加泛型参数、唯一基类、实现多个接口
//public 为修饰符
public class MyClass{
}
- 类成员
有 字段 ,属性,构造器,解构器, 方法,事件,索引器,终结器 ,重载运算符
1. 字段
字段可以用以下修饰符进行修饰
- 静态修饰符:static
- 访问修饰符:public,internal,private,protected
- 继承修饰符:new
- 不安全代码修饰符:unsafe
- 只读修饰符:readonly 只能在声明时或类构造器中赋值,其他地方无法更改
- 线程访问修饰符:volatile
internal class Person
{
private readonly string name="xiaoli";
private int age = 18;
public Person()
{
name = "zhangwei";
age = 20;
}
public override string ToString()
{
//this.name = "zhangsan"; //无法修改 readonly
return this.name+","+this.age;
}
}
2. 属性
通常属性是公有,字段是私有
属性可以用以下修饰符:
- 静态修饰符:static
- 访问权限修饰符:public ,internal , private , protected
- 继承修饰符: new , virtual ,abstract ,override ,sealed
- 非托管代码修饰符:unsafe , extern
//1.基本用法
internal class Person
{
//属性初始化
public string Name {
get; set; } = "xiaoli";
public int Age {
get; set; } = 18;
public override string ToString()
{
return this.Name+","+this.Age;
}
}
static void Main(string[] args)
{
Person p = new Person();
p.Age = 18;
p.Name = "zhangwei";
Console.WriteLine(p.ToString());
Console.ReadLine();
}
//输出
xiaoli,18
//2.属性搭配字段使用
internal class Person
{
private string name;
private int age;
public string Name {
get => name; set => name = value; }
public int Age {
get => age; set => age = value; }
public override string ToString()
{
return this.Name+","+this.Age;
}
}
static void Main(string[] args)
{
Person p = new Person();
p.Age = 18;
p.Name = "zhangwei";
Console.WriteLine(p.ToString());
Console.ReadLine();
}
//输出
zhangwei,18
//给属性 set 添加私有访问修饰符
internal class Person
{
private string name;
private int age;
public string Name {
get => name; set => name = value; }
public int Age {
get => age; private set => age = value; }
public override string ToString()
{
this.Age = 20;
return this.Name+","+this.Age;
}
}
static void Main(string[] args)
{
Person p = new Person();
p.Name = "zhangwei";
Console.WriteLine(p.ToString());
Console.ReadLine();
}
//输出
zhangwei,20
3. 构造器
隐式无参构造器:默认有一个无参构造器,但是如果显示写一个有参或无参构造器,则该无参构造器自动消失,必须手动添加一个无参构造器。默认无参构造器中的字段值为默认类型值或者是字段声明时的初始化值。
internal class Person
{
//这里的 ? 是指这个字段可以为 null
private string? name;
private int age;
//无参构造器
public Person()
{
name = "zhang";
age = 18;
}
//有参构造器
public Person(string? name,int age)
{
this.name = name;
this.age = age;
}
public string? Name {
get => name; set => name = value; }
public int Age {
get => age; set => age = value; }
public override string ToString()
{
return this.name+","+this.age;
}
}
static void Main(string[] args)
{
Person p = new Person("xiaoli",20);
Person p1 = new Person();
Console.WriteLine(p.ToString());
Console.WriteLine(p1.ToString());
Console.ReadLine();
}
//输出
xiaoli,20
zhang,18
4. 解构器
要求C# 7.0以上
这里的解构器可以看做是构造器的反向操作,解构器可以把一个对象赋值给一个元组
解构器必须要下面这种形式,必须是Deconstruct这个名字,必须要有out传出参数。
public void Deconstruct(out string? name,out int age)
internal class Person
{
private string? name;
private int age;
public Person()
{
name = "zhang";
age = 18;
}
public Person(string? name,int age)
{
this.name = name;
this.age = age;
}
public string? Name {
get => name; set => name = value; }
public int Age {
get => age; set => age = value; }
//必须要
public void Deconstruct(out string? name,out int age)
{
name = Name;
age = Age;
}
public override string ToString()
{
return this.name+","+this.age;
}
}
static void Main(string[] args)
{
Person p = new Person();
(string? name, int age) = p;
Console.WriteLine(name+","+age);
Console.ReadLine();
}
//输出
zhang,18
5.方法
方法可以用以下修饰符修饰
- 静态修饰符:Static
- 访问修饰符:public , internal , private , protected
- 继承修饰符:new , virtual , abstract, override , sealed
- 部分方法修饰符: partial
- 非托管代码修饰符:unsafe , extern
- 异步代码修饰符:async
其他比如重载方法,使用 ref 引用传递,过程略。
6. 事件
需要搭配委托使用,暂略。
7. 索引器
索引器一般是数组用的东西,但是类中也有这个方法。
简单来说,类的索引器就是重写 [ ] 中括号这个
internal class PersonIntroduce
{
private string? content;
private string[]? conts;
public PersonIntroduce()
{
content = "this is introduce";
conts = content.Split();
}
public PersonIntroduce(string content)
{
this.content = content;
conts = content.Split();
}
public string this[int index]
{
get {
return conts[index]; }
set {
conts[index] = value; }
}
}
static void Main(string[] args)
{
PersonIntroduce pi = new PersonIntroduce();
string str = pi[1];
Console.WriteLine(str);
pi[1] = "times";
Console.WriteLine(pi[1]);
Console.ReadLine();
}
//输出
is
times
8. 终结器
终结器(Finalizer),在垃圾回收器回收未引用的对象占用的内存前调用。
终结器可以被 非托管代码修饰符 unsafe 修饰。
internal class PersonIntroduce
{
public PersonIntroduce()
{
Console.WriteLine("开始");
}
~PersonIntroduce(){
Console.WriteLine("结束了");
}
}
static void Main(string[] args)
{
PersonIntroduce pi = new PersonIntroduce();
}
9. 重载运算符
internal class PersonIntroduce
{
private int a;
public int A {
get => a; set => a = value; }
public PersonIntroduce()
{
a = 1;
}
~PersonIntroduce()
{
Console.WriteLine("结束了");
}
public static PersonIntroduce operator +(PersonIntroduce a, PersonIntroduce b)
{
PersonIntroduce per = new PersonIntroduce();
per.a = a.a + b.a;
return per;
}
}
static void Main(string[] args)
{
PersonIntroduce pi = new PersonIntroduce();
PersonIntroduce pj = new PersonIntroduce();
Console.WriteLine((pi + pj).A);
}
//输出
2
10. 分部方法
方法的声明和定义可以在不同文件里面,但是需要再同一个命名空间,添加 partial 关键字
partial class PersonIntroduce
{
partial void Add();
}
partial class PersonIntroduce
{
partial void Add()
{
}
}
nameof方法
可以返回任意类型或者成员或者变量的字符串名称
Person p = new Person();
string name = nameof(p); //输出 p
int num = 10;
string name = nameof(num); //输出 num
GetType 方法和 typeof方法
使用这个两个方法可以获取当前对象的类,两个都是返回的 System.Type 类型
Dog dog = new Dog();
Console.WriteLine(dog.GetType() == typeof(Dog));
ToString方法
可以在类中重写该方法
结构体
结构体和类相比,结构体是值类型,类是引用类型。结构体无法继承。
结构体可以包含:
- 字段初始化器
- 无参数的构造器
- 终结器
- 虚成员或 protected 成员
public struct Point{
int x,y;
public Point(int x,int y){
this.x = x; this.y = y;}
}