No title

简述装箱拆箱

1
装箱是指将值类型(int,float等)转换为对象类型object类型的过程,拆箱是将对象类型转换为原始类型的过程,装箱操可以通过赋值操作自动实现,拆箱操作要强制类型转换,如果转换类型和原类型不匹配会抛出类型转异常。

class 和 struct

1
2
3
4
5
6
7
结构是值类型,而类是引用类型。
向方法传递结构时,结构是通过传值方式传递的,而不是作为引用传递的。
与类不同,结构的实例化可以不使用 new 运算符。
结构可以声明构造函数,但它们必须带参数。
一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自 System.Object。
结构可以实现接口。
在结构中只能用构造函数来实例化属性,不能声明的时候直接赋值

类的分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1.1 抽象类
关键字: abstract
使用目的:若所有子类拥有共同的特性,可以把这个特性放到一个抽象类中,子类继承此抽象类。
特点:
1.不能被实例化;ClassName en=new ClassName();
//这样会报错。
2.抽象成员必须包含在抽象类中。
3.抽象类除了抽象成员外,还可以包含别的成员(不用关键字 abstract)。
4.子类继承抽象父类后,必须把父类中的所有抽象成员都重写(非抽象成员不必重写)。除非子类也是个抽象类,抽象属性的get或set方法也得重写。
5.抽象成员的访问修饰符不能是private。
6.抽象类是有构造函数,虽然不能被实例化。
7.abstract不能用于字段成员,可定义成属性。
8.abstract用于方法时,方法不能定义主体(内容)。
9.抽象类也可以实现接口,但要把接口的成员前面标记个abstract。

1.2 密封类
关键字:sealed
使用目的:不需要子类来继承他。如 String;
特点:
1.不能被继承,如:string ,不能被继承。
2.子类重写后,前面加个sealed,那么子类就不能再被继承。

1.3 静态类
关键字: static
使用目的:不需要实例化,可以直接类名引用静态方法。比如 工具类。
特点:
1.相似于sealed与abstract使用。
2.静态成员在整个程序退出时才释放资源,所以尽量别写静态字段、属性。最好是静

2. 接口
关键字:interface
使用目的:抽象类所拥有的共性,也可以概括为:为了多态。
特点:
1.接口中只能包含方法。(方法、属性、索引器、事件)
2.接口中的方法不能有任何实现
3.接口中的成员不能有任何访问修饰符(哪怕是public)
4.接口不能被实例化
5.实现接口的类,必须实现接口的所有成员(这里跟抽象类一样)
6.类不能多继承,所以在某些情况下,只能用接口来代替。接口可以多实现(一个类可以继承多个接口,而只能继承一个类)
7.接口的主要目的就是为了实现多态
8.当一个类,同时继承了某个类,并且也实现了某些接口的时候,必须要将继承的类写在第一个(如果一个类同时继承了父类和接口的时候,要把父类写在最前面)
9.当多个类,都具有某个或某几个功能时(方法),但是这几个类型又不属于相同的系列(这几个类型没有共同的父类,就不能用抽象类。),所以这时,为了实现多态就可以考虑把这几个类型共有的方法提取到一个接口中,让这几个类型分别实现该接口
10.当父类实现接口,子类继承父类。那么 接口就可以引用子类
11.不要在一个接口中写过多的方法,避免造成接口污染。可编写多个接口,在每个接口中,分别定义方法
12.实现接口方法的时候,不要有override关键字,直接跟平常定义一样
13.接口方法的显示实现,如果多个接口里有相同的方法名。那么第一个方法名


接口和类的异同

1
2
3
4
5
6
7
8
9
10
11
12
13
  接口和类不同点:
不能直接实例化接口。
接口不包含方法的实现。
接口可以多继承,类只能单继承。
类定义可以在不同的源文件之间进行拆分。

接口和类相同点:
接口、类和结构都可以从多个接口继承。
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
接口和类都可以包含事件、索引器、属性。
接口只能定义方法。

抽象方法不能被声明为`static`。因为抽象方法的主要目的是在派生类中被重写(override)。而静态方法属于类本身,不能被派生类重写。因此,抽象方法和静态方法的概念是相互矛盾的。

C#构造器Constructor是否可以被继承?是否可以被Override?

  1. 在C#中,构造器(Constructor)既不是继承的也不是被重写的(Override)。这里有几个关键点需要澄清:
    
    1. **构造器不是继承的**:当你创建一个派生类(子类)时,它不会自动继承基类的构造器。相反,每个类都必须有自己的构造器(除非它是`struct`类型,它默认有一个无参数的构造器,但`struct`不支持继承)。如果基类有构造器,并且你想要在派生类中使用它(比如,你想要初始化基类的一部分状态),你需要在派生类的构造器中使用`base`关键字显式地调用它。但是,这并不是说派生类“继承”了基类的构造器,而是派生类构造器负责调用基类构造器(如果需要的话)。
    2. **构造器不能被重写**:在C#中,`override`关键字用于重写基类中的虚方法(virtual methods)、抽象方法(abstract methods)、属性(properties)、索引器(indexers)和事件(events)。然而,构造器不是这些方法、属性、索引器或事件之一,因此它们不能被重写。每个类都有自己的一组构造器,这些构造器是特定于该类的,并且不能通过继承机制来修改或替换。
    3. **构造器的调用链**:当你创建派生类的一个实例时,首先会调用派生类的构造器。然后,派生类构造器可以使用`base`关键字来调用基类构造器(这是可选的,但通常是必要的,特别是当基类有非默认构造器时)。这个过程会一直向上追溯到类的继承链的顶部,直到最终调用到`System.Object`的构造器(这是所有C#类的最终基类)。这个调用链确保了基类在派生类之前被正确初始化。
    
    1
    2
    3
    4
    5



    C#虚方法(virtual )和抽象方法(abstract)的区别?

一:抽象方法仅有声明,而没有任何实现,如abstract someMethod();,虚方法却不能如此
二:子类继承父类,可以对父类中的虚方法进行重写、覆盖、不处理三种处理对抽象方法却必须实现

子类对父类中虚方法的处理有重写(override)和覆盖(new),请说明它们的区别?
有父类ParentClass和子类ChildClass、以及父类的虚方法VirtualMethod。有如下程序段:
ParentClass pc = new ChildClass();
pc.VirtualMethod(…);
如果子类是重写(override)父类的VirtualMethod,则上面的第二行语句将调用子类的该方法
如果子类是覆盖(new)父类的VirtualMethod,则上面的第二行语句将调用父类的该方法

1
2
3
4
5
6




简述 private、 protected、 public、 internal 修饰符的访问权限 ?

private : 私有成员, 在类的内部才可以访问 ,也就是类内部的函数等成员可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
internal: 当前程序集内可以访问

1
2
3
4


C#支持多重继承么?

类之间不支持,接口之间支持。类对接口叫做实现,不叫继承

1
2
3
4
5
6




c#解释什么是构造函数?

概念:构造函数的⽅法名与类型相同、没有返回类型
作⽤:完成对类的对象初始化创建⼀个类的新对象时,系统会⾃动调⽤该构造函数初始化新对象, 如果没有写定义,那么系统会⾃动提供⼀个不带任何参数的public 构造函数

1
2
3
4


简述⼀下⾯向对象的三⼤特性?

1. 封装(Encapsulation)

封装是指将数据(属性)和操作数据的代码(方法)封装在一个对象内部,隐藏对象的属性和实现细节,仅对外提供公共的访问方式(如getter和setter方法)。这样做的目的是提高代码的安全性、可维护性和可重用性。封装使得对象的设计者与使用者分离,使用者只需要通过公共接口与对象交互,而不需要知道对象内部的具体实现细节。

2. 继承(Inheritance)

继承是一种创建新类的方式,新创建的类(称为子类或派生类)可以继承一个或多个已存在的类(称为父类或基类)的属性和方法。子类可以拥有父类的所有属性和方法(除非在子类中进行了重写或隐藏),同时子类还可以添加自己特有的属性和方法。继承提高了代码的重用性和可扩展性,通过继承,我们可以方便地创建出具有层次结构的类体系。

3. 多态(Polymorphism)

多态是指允许不同类的对象对同一消息作出响应,即同一操作作用于不同的对象时,可以产生不同的结果。多态性可以通过方法重写(Override)和方法重载(Overload)来实现。方法重写是子类对父类方法的重新实现,子类对象调用该方法时将执行子类中的实现版本。方法重载是在同一个类中定义多个同名方法,但它们的参数列表不同,这样可以根据传入参数的不同来调用不同的方法。多态性提高了代码的灵活性和可扩展性,使得我们可以编写更加通用和可复用的代码。

1
2
3
4
5
6




构造函数是否能被重写?

不能可以但可以被重载

1
2
3
4


C# 类的执⾏顺序?

执⾏顺序:⽗类,⼦类,静态块,静态字段,⾮静态块,⾮静态字段,构造器,⽅法

1
2
3
4
5
6




请说说C#引⽤和对象?

1.对象:目前在使用new运算符在堆内存中开辟的内存空间称为对象。
2.引用:引用时一个变量,不一定是局部变量,还可能是成员变量。引用保存了内存地址,指向了堆内存当中的对象。

1
2
3
4


C#属性能在接⼝中声明吗?

可以在接口中声明但不能初始化,可以声明属性的get,set方法,不能实现。

接口的好处

接⼝是⼀种约束,描述类的公共⽅法/公共属性,不能有任何的实现
好处是:结构清晰,类之间通信简单易懂,扩展性好,提⾼复⽤性。
⾯向interface编程,原意是指⾯向抽象协议编程,实现者在实现时要严格按协议来办

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


C#中有没有静态构造函数,如果有是做什么⽤的?

1. ```
1. 是的,C# 中有静态构造函数(Static Constructors)。静态构造函数在类中仅有一个,并且不能被直接调用。它是在类被加载到 CLR(公共语言运行时)时自动调用的,且仅被调用一次,以初始化类的静态成员。

静态构造函数的主要用途包括:

1. **初始化静态成员**:静态构造函数是初始化类级别的静态变量或执行仅需运行一次的静态初始化代码的理想位置。这些变量或代码在类的任何静态成员被访问之前执行,确保了类的静态状态的一致性和正确性。
2. **执行一次性的类级设置**:如果你的类需要执行一些一次性的设置或配置,比如加载配置文件、初始化日志记录器等,静态构造函数是一个很好的地方来做这些事情。
3. **确保线程安全**:由于静态构造函数在类被加载到CLR时自动调用,且只调用一次,因此它是执行线程安全的一次性初始化代码的理想选择。CLR保证了静态构造函数在多个线程同时尝试首次使用类时,只会被一个线程调用。

C#能⽤foreach遍历访问的对象需要实现 接⼝或声明⽅法的类型?(c#自定义可迭代类型)

​ 实现IEnumerable<T>接口的GetEnumerator方法

​ 实现非泛型的IEnumerable接口的GetEnumerator方法

C#中的析构函数是什么?

1
2
3
4
5
6
7
8
9
在C#中,析构函数(Destructor)是一个特殊的方法,用于在对象被垃圾回收器(Garbage Collector, GC)销毁之前执行清理操作。析构函数不能带任何参数,也不能被显式调用;它是由.NET运行时自动调用的,当垃圾回收器确定对象不再被应用程序中的任何部分引用时。
class MyClass
{
~MyClass()
{
// 清理代码
Console.WriteLine("MyClass destructor called.");
}
}

解释C#中什么是命名空间,它是强制性的吗?

1
2
3
4
5
6
7
8
9
10
在C#中,命名空间(Namespace)是一种封装命名空间成员(类型、接口、委托、枚举等)的方式,它提供了一个逻辑上的分组和层次结构,帮助组织代码,避免命名冲突,以及使得代码更加模块化。命名空间的使用是可选的,不是强制性的,但它是一个被广泛推荐的最佳实践。

### 命名空间的定义

命名空间通过`namespace`关键字来定义。一个命名空间可以包含多个类、接口、结构体、枚举等,并且这些成员可以被嵌套在更深层次的命名空间中,以形成命名空间的层次结构。
虽然命名空间的使用不是强制性的,但在实际开发中,它几乎总是被使用的。不使用命名空间可能会导致以下问题:

命名冲突:如果项目中不使用命名空间,那么所有类型的名称都必须全局唯一,这在实际项目中几乎是不可能的。
代码混乱:没有命名空间,项目中的代码将难以组织和维护,特别是在大型项目中。
可读性降低:没有命名空间的结构,代码的阅读和理解将变得更加困难。

阐述什么是C# static关键字?

1
2
3
4
5
我们使用 static 关键字来创建静态类、静态方法或静态属性。当我们创建一个静态类时,该类中只能有静态数据成员和静态方法。静态意味着我们不能创建该类的实例。该类可以像 ClassName.methodName 一样直接使用。

我们可以在C#静态类中使用“this”吗 ?

“this”不能与静态类一起使用,因为我们只能在静态类中使用静态变量和静态方法