50 个最热门 C# 面试问题及答案 (2025)

面向应届毕业生和 2/3/5/10 年经验者的 C# 面试问题和答案

以下是 C# 面试问题和答案,可帮助应届毕业生以及具有 5 年或 10 年经验的应聘者获得理想的工作。

1)什么是 C#?

C# 是一种面向对象、类型安全且托管的语言,由 .Net 框架编译以生成 Microsoft 中级语言。

👉 免费 PDF 下载:C# 面试 面试问题与答案


2)解释评论类型 C# 有例子

单线

计费示例:

//This is a single line comment

ii. 多行(/* */)

计费示例:

/*This is a multiple line comment
We are in line 2
Last line of comment*/

iii. XML 注释(///)。

计费示例:

/// summary;
/// Set error message for multilingual language.
/// summary

3)是否可以执行多个catch块?

不可以,不能执行多个类似类型的 catch 块。一旦执行了正确的 catch 代码,控制权就会转移到 finally 块,然后执行 finally 块后面的代码。


4)public、static、void有什么区别?

公共声明的变量或方法可在应用程序的任何位置访问。静态声明的变量或方法可在全局访问,无需创建类的实例。静态成员默认不是全局可访问的,这取决于使用的访问修饰类型。编译器将方法的地址存储为入口点,并在创建任何对象之前使用此信息开始执行。Void 是一种类型修饰符,表示方法或变量不返回任何值。

C# 中的对象

C# 面试问题


5)什么是对象?

对象是类的一个实例,我们可以通过它访问该类的方法。“New”关键字用于创建对象。在内存中创建对象的类将包含有关该类的方法、变量和行为的信息。


6)定义构造函数

构造函数是类中与类同名的成员函数。每当创建对象类时,都会自动调用构造函数。它在初始化类时构造数据成员的值。


7)什么是锯齿数组?

具有数组类型元素的数组称为交错数组。元素可以具有不同的维度和大小。我们也可以将交错数组称为数组的数组。


8)ref 和 out 参数有什么区别?

作为 ref 传递的参数在传递给方法之前必须进行初始化,而 out 参数在传递给方法之前无需进行初始化。


9)C# 中的“using”语句有什么用途?

“使用”块用于获取资源并处理它,然后在块执行完成时自动处理。


10)什么是序列化?

当我们想通过网络传输对象时,我们必须将对象转换为字节流。将对象转换为字节流的过程称为序列化。要使对象可序列化,它应该实现 ISerialize 接口。反序列化是从字节流创建对象的逆过程。


11) 我们可以在静态方法中使用“this”命令吗?

我们不能在静态方法中使用“This”,因为我们只能在静态方法中使用静态变量/方法。


12)常量和只读有什么区别?

常量变量在编译时声明并初始化。之后不能更改其值。仅当我们想在运行时分配值时才使用只读。


13)什么是接口类?举一个例子

接口是一个抽象类,只有公共的抽象方法,这些方法只有声明而没有定义。这些抽象方法必须在继承的类中实现。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DemoApplication
{
 interface Guru99Interface
 {
  void SetTutorial(int pID, string pName);
  String GetTutorial();
 }

 class Guru99Tutorial : Guru99Interface
 {
  protected int TutorialID;
  protected string TutorialName;

  public void SetTutorial(int pID, string pName)
  {
   TutorialID = pID;
   TutorialName = pName;
  }

  public String GetTutorial()
  {
   return TutorialName;
  }

  static void Main(string[] args)
  {
   Guru99Tutorial pTutor = new Guru99Tutorial();

   pTutor.SetTutorial(1,".Net by Guru99");

   Console.WriteLine(pTutor.GetTutorial());

   Console.ReadKey();
  }
 }
}

14)什么是值类型和引用类型?

值类型在它自己的内存空间中保存数据值。示例

int a = 30;

引用类型存储了存储值的对象的地址。它是指向另一个内存位置的指针。

string b = "Hello Guru99!!";

15)什么是自定义控件和用户控件?

自定义控件是作为编译代码 (Dll) 生成的控件,它们更易于使用,并且可以添加到工具箱中。开发人员可以将控件拖放到他们的 Web 表单中。属性可以在设计时添加。我们可以轻松地将自定义控件添加到多个应用程序(如果是共享 Dll)。因此,如果它们是私有的,那么我们可以将 dll 复制到 Web 应用程序的 bin 目录中,然后添加引用并使用它们。

用户控件与 ASP 包含文件非常相似,并且易于创建。用户控件不能放在工具箱中并从中拖放。它们有自己的设计和隐藏代码。用户控件的文件扩展名为 ascx。


16) C# 中的密封类是什么?

当我们想要限制类被继承时,我们会创建密封类。密封修饰符用于防止从类派生。如果我们强制指定密封类作为基类,则会发生编译时错误。


17)什么是方法重载?

方法重载是指在同一个类中创建多个具有相同名称和唯一签名的方法。在编译时,编译器使用重载解析来确定要调用的具体方法。


18)Array 和 Arraylist 有什么区别?

在数组中,我们只能拥有相同类型的项目。相比之下,数组的大小是固定的。arraylist 类似于数组,但它没有固定的大小。


19) 私有虚方法可以被重写吗?

不可以,因为课堂外无法访问它们。


20) 描述可访问性修饰符“protected internal”。

受保护的内部变量/方法可在同一程序集内访问,也可从该父类派生的类访问。


21) System.String 和 System.Text.StringBuilder 类之间有什么区别?

System.String 是不可变的。当我们修改字符串变量的值时,会为新值分配新的内存,并释放之前的内存分配。System.StringBuilder 的设计理念是可变字符串,无需为修改后的字符串分配单独的内存位置,即可执行各种操作。


22) System.Array.CopyTo() 和 System.Array.Clone() 之间有什么区别?

运用 Clone() 方法,我们创建一个包含原始数组中所有元素的新数组对象,并使用 CopyTo() 方法。现有数组的所有元素都复制到另一个现有数组中。两种方法都执行浅复制。


23) 如何按降序对数组元素进行排序?

运用 Sort() 所采用的方法 Reverse() 方法。


24)写下 C# 捕获异常的语法

为了捕获异常,我们使用 try-catch 块。Catch 块可以有一个 system.Exception 类型的参数。

例如:

try {
    GetAllData();
} 
catch (Exception ex) {
}

在上面的例子中,我们可以省略 catch 语句中的参数。


25)接口和抽象类有什么区别?

接口的所有方法都只有声明,没有定义。在抽象类中,我们可以有一些具体的方法。在接口类中,所有方法都是公共的。抽象类可以有私有方法。


26) Finalize() 和 Dispose() 方法有什么区别?

Dispose() 当我们想要对象释放任何非托管资源时,就会调用此方法。另一方面, Finalize() 用于相同目的,但它不能保证对象的垃圾收集。


27)什么是循环引用?

循环引用是指两个或多个资源相互依赖的情况,从而导致锁定情况并使资源无法使用。


28) C#.NET 中的泛型是什么?

泛型用于创建可重用的代码类,以减少代码冗余、提高类型安全性和性能。使用泛型,我们可以创建集合类。要创建泛型集合,应使用 System.Collections.Generic 命名空间,而不是 System.Collections 命名空间中的 ArrayList 等类。泛型促进了参数化类型的使用。


29).NET 中的对象池是什么?

对象池是一个容器,里面存放着随时可用的对象。它跟踪当前正在使用的对象,以及池中的对象总数。这减少了创建和重新创建对象的开销。


30)列出.net中常用的异常类型

ArgumentException、ArgumentNullException、ArgumentOutOfRangeException、ArithmeticException、DivideByZeroException、OverflowException、IndexOutOfRangeException、InvalidCastException、无效OperationException、IOEndOfStreamException、NullReferenceException、OutOfMemoryException、StackOverflowException 等。


31)什么是自定义异常?

有时,有些错误需要根据用户要求进行处理。自定义异常和定义异常都可用于处理这些错误。


32)什么是代表?

委托与函数指针相同 C++,但唯一的区别是它们是类型安全的,不像函数指针。委托是必需的,因为它们可用于编写更通用的类型安全函数。


33) 在 C# 中,如何将一个类继承为另一个类?

在 C# 中,冒号用作继承运算符。只需放置冒号,然后放置类名。

public class DerivedClass : BaseClass

34) .net 中所有类均派生自哪个基类?

System.Object

35) 方法重写和方法重载有什么区别?

在方法覆盖中,我们更改派生类中的方法定义,从而改变方法行为。方法重载是在同一个类中创建具有不同签名的同名方法。


36) 方法重载有哪些不同的方式?

可以使用不同的参数数据类型、不同的参数顺序和不同的参数数量来重载方法。


37) 为什么不能为接口内部的方法指定可访问性修饰符?

在接口中,我们有虚拟方法,这些方法没有方法定义。所有方法都可以在派生类中重写。这就是为什么它们都是公共的。


38) 如何设置类可以被继承,但方法不能被重写?

将该类声明为公共,并将方法密封,以防止其被覆盖。


39) 如果继承的接口有冲突的方法名称会发生​​什么?

实现由您决定,因为该方法位于您自己的类中。当来自不同接口的方法需要不同的数据时,可能会出现问题,但就编译器而言,您没问题。


40) 结构体和类有什么区别?

结构体是值类型变量,而类是引用类型。结构体存储在堆栈中会产生额外开销,但检索速度更快。结构体不能被继承。


41) 如何在.Net 中使用可空类型?

值类型可以采用其正常值或空值。此类类型称为可空类型。

Int? someID = null;
If(someID.HasVAlue)
{
}

42) 如何创建具有非默认值的数组?

我们可以使用 Enumerable.Repeat 创建一个具有非默认值的数组。


43) C# 中“is”和“as”运算符有什么区别?

“is”运算符用于检查对象与给定类型的兼容性,并以布尔值形式返回结果。

“as”运算符用于将对象转换为某种类型或类。


44)什么是多播委托?

被分配了多个处理程序的委托称为多播委托。每个处理程序被分配给一个方法。


45) C# .NET 中的索引器是什么?

索引器被称为智能 C# 中的数组. 它允许以与数组相同的方式对类的实例进行索引。

例如:

public int this[int index]    // Indexer declaration

46).NET 中的“throw”和“throw ex”有什么区别?

“Throw” 语句保留原始错误堆栈,而“throw ex” 则保留从其抛出点开始的堆栈跟踪。始终建议使用“throw”,因为它提供更准确的错误信息。


47) 什么是 C# 属性及其重要性?

C# 为开发人员提供了一种定义某些实体的声明性标记的方法,例如类、方法等被称为属性。可以使用反射在运行时检索属性的信息。


48) 如何在 C# 中实现单例设计模式?

在单例模式中,一个类只能有一个实例,并全局提供一个对它的访问点。

例如:

Public sealed class Singleton
{
Private static readonly Singleton _instance = new Singleton();
}

49)directcast 和 ctype 有什么区别?

DirectCast 用于转换要求运行时类型与 DirectCast 中指定的类型相同的对象的类型。

Ctype 用于转换,其中转换是在表达式和类型之间定义的。


50)C# 代码是托管代码还是非托管代码?

C# 是托管代码,因为公共语言运行时可以将 C# 代码编译为中间语言。


51)什么是控制台应用程序?

控制台应用程序是可以在命令提示符中运行的应用程序 Windows。 对于任何 .Net 初学者首先,构建控制台应用程序是理想的第一步。


52)给出一个从队列中删除元素的示例

dequeue 方法用于从队列中删除元素。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoApplication
{
 class Program
 {
  static void Main(string[] args)
  {
   Queue qt = new Queue();
   qt.Enqueue(1);
   qt.Enqueue(2);
   qt.Enqueue(3);

   foreach (Object obj in qt)
   {
    Console.WriteLine(obj);
   }
    Console.WriteLine(); Console.WriteLine();
    Console.WriteLine("The number of elements in the Queue " + qt.Count);
    Console.WriteLine("Does the Queue contain " + qt.Contains(3));
    Console.ReadKey();
   }
 }
}

这些面试问题也会对你的口试有帮助