我们整理了60个常见的C#面试问题和答案,包括初级,中级和高级面试问题。对即将参加面试的同学非常有用,建议收藏研读。
许多雇主对只会纸上谈兵的程序员都保持持谨慎态度,特别是没有编程经验但而有学位的人。正因为如此,他们经常在面试中提出深入的编程问题。如果你没有做好充分的准备,这些问题可能很难回答。
在本文中,我将帮助你准备好在下一次面试中解决这些与C# 编程语言相关的问题。同时,你可能想练习一些C# 项目。这 60 个基本的 C#面试问题和答案将帮助你了解该语言的技术概念。
什么是 C#?
C# 于 2000 年发布,是一种基于 C 的编程语言,用于从桌面应用程序到 Web 服务的所有内容。今天,C# 是世界上最流行的编程语言之一,它是一种在编程领域备受追捧的语言。
C# 在几个主要方面与 C++不同。最明显的是,C# 是一种基于组件的语言,而 C++ 是一种面向对象的语言。C# 被认为比 C++ 更重量级,但它被用于许多现代系统,例如游戏开发工具包。初学者 C# 面试问题和答案
1.什么是类?
类是创建对象的模板。它包含属性和方法。我们可以从一个类创建许多对象实例。下面是一个类的例子:
public class Student { //data members public int rollNumber { get; set; } public string fullName { get; set; } //function public void PrintDetails() { //login of function } }
2.面向对象编程的主要概念是什么?
封装、抽象、多态和继承是面向对象编程的主要概念。准备好描述其中的每一个。面向对象编程与过程编程的不同之处在于过程编程按时间顺序、逐步进行,而面向对象编程则灵活得多。
3.什么是对象?
对象是一个类的实例,我们通过它访问该类的功能。我们可以使用“new”关键字来创建一个对象。在内存中创建对象的类保存有关该类的函数、数据成员和行为的信息。请参阅下面的对象语法。
//Class public class Employee { //private members private string fName { get; set; } private string lName { get; set; } //function public void Display() { Console.WriteLine("Full name is {0} {1}", fName, lName); } public void SetName(string firstName, string lastName) { fName = firstName; lName = lastName; } } class Program { static void Main(string[] args) { //this is object Employee employee = new Employee(); employee.SetName("John", "Grande"); employee.Display(); } }
4.什么是构造函数,它有哪些不同的类型?
构造函数就像一个与类同名的方法,但它是唯一的方法。即使没有创建,编译器也会在创建类的对象时在内存中创建一个默认构造函数。构造函数用于使用一些默认值初始化对象。默认构造函数、参数化构造函数、复制构造函数、静态构造函数和私有构造函数都是不同的构造函数类型。下面是不同构造函数类型的示例。
public class Student { private int rollNumber { get; set; } private string fullName { get; set; } //default constructor public Student() { //code goes here } //parameterized constructor public Student(int rNum, string fName) { this.rollNumber = rNum; this.fullName = fName; } //static constructor static Student() { //code goes here } //copy constructor public Student(Student student) { rollNumber = student.rollNumber; fullName = student.fullName; } }
5. C#中的析构函数是什么?
析构函数清除内存以释放资源,并由垃圾收集器自动管理。为此目的在内部调用 System.GC.collect()。但是,如果需要,可以使用析构函数显式完成。
public class Purchase { //Syntax to write a destructor. ~Purchase() { //code here to release resources. }}
6. C# 代码是托管代码还是非托管代码?
C# 是托管代码,因为公共语言运行时将代码编译为中间语言代码。C++ 将提供非托管代码的示例。托管代码只是指其执行由运行时管理的代码。
7.什么是值类型和引用类型?
我们可以将变量分为值类型和引用类型。值类型变量直接包含值,而引用类型变量包含内存地址的引用,其中值实际存储在内存中。Bool、byte、int、char 和 decimal 是值类型。字符串、类、委托都是引用类型。
8.什么是命名空间,它是强制性的吗?
命名空间是一种以相同名称组织相同组或功能的类的方法。我们可以称它为模块。尽管将类放在命名空间中并不是强制性的。请参阅下面的语法。
namespace demoapp{ class SomeClass { public static void someMethod() { Console.WriteLine("Creating my namespace"); } }}
9.用例子解释 C# 中的注释类型。
C# 中有三种类型的注释。
单行注释的示例是://嘿,这是单行注释
多行注释的一个例子是:/*这是一个多行注释写成两行*/
XML 注释的一个示例是:///概括///这里可以写任何东西///概括
Code with Mosh - 通过编码学习 C# 基础知识
https://www.koudaizy.com/tutorials/csharp-tutorial-for-beginners/
10.请解释封装。
封装是将函数和数据成员包装在一个类中的过程;它就像一个胶囊,一个单一的单元。封装可防止来自函数外部的未经授权或不需要的数据更改。它用于更好地控制和标准化你的代码。下面是一个封装的例子。
class User { private string address; private string name; public string Address { get { return address; } set { address = value; } } public string Name { get { return name; } set { name = value; } } } class MyProgram { static void Main(string[] args) { User u = new User(); // set accessor will invoke u.Name = "Ravi"; // set accessor will invoke u.Address = "New Delhi"; // get accessor will invoke Console.WriteLine("Name: " + u.Name); // get accessor will invoke Console.WriteLine("Location: " + u.Address); Console.WriteLine("nPress Enter Key"); Console.ReadLine(); }}
11.什么是抽象?
抽象是只暴露类的必需特性并隐藏不必要信息的方法。我们可以尝试以摩托车为例来理解它:骑手知道自行车的颜色、名称和型号。尽管如此,他们仍然不了解内部发动机和排气功能。同样,抽象侧重于提供对特定功能的访问,而不暴露该功能在内部是如何工作的。
12.什么是多态性?
多态意味着相同的方法但不同的实现。有两种类型的多态性。
public class cellphone { //function with the same name but different parameters. public void Typing() { Console.WriteLine("Using keypad"); } public void Typing(bool isSmartPhone) { Console.WriteLine("Using qwerty keyboard"); }}
public class CellPhone { public virtual void Typing() { Console.WriteLine("Using keypad"); } } public class SmartPhone : CellPhone { //method override public override void Typing() { Console.WriteLine("Typing function from child class"); }}
13.定义一个界面并展示一个例子。
接口是抽象类的另一种形式,它只有抽象的公共方法。这些方法只有声明,没有定义。实现接口的类必须实现接口的所有方法。例如:
interface IPencil { void Write(string text); void Sharpen(string text); } class Pencil : IPencil { public void Write(string text) { //some code here } public void Sharpen(string text) { //some code here } } public class CellPhone { public virtual void Typing() { Console.WriteLine("Using keypad"); }}
14.什么是继承?
一个类可以从另一个类(称为其父类)继承数据成员和方法。继承属性和方法的类将被称为子类、派生类。派生类中的某些属性可以被覆盖。从类继承特征的能力使管理类的整个过程变得更加容易,因为你可以创建自定义的子类。原始类将被称为父类或基类。请参考以下示例:
class Mobile // base class (parent) { public void call() { Console.WriteLine("calling...!"); } } class Nokia : Mobile // derived class (child) { public string modelName = "Nokia"; } class MyProgram { static void Main(string[] args) { // Create a myNokia object Nokia myNokia = new Nokia(); // Calls the call() method (From the Mobile class) on the myNokia object myNokia.call(); }}
中级 C# 编程问题
15.如何在同一个类中实现多个具有相同方法名的接口?
要实现具有相同方法名称的多个接口,你将避免在函数体中实现。相反,你将显式地将接口名称提供给方法的主体。编译器将了解所引用的接口方法,从而解决问题。这可以在以下示例中看到:
interface myInterface1 { void Print(); } interface myInterface2 { void Print(); } class Student : myInterface1, myInterface2 { void myInterface1.Print() { Console.WriteLine("For myInterface1 !!"); } void myInterface2.Print() { Console.WriteLine("For myInterface2 !!"); }}
16.什么是虚方法,它与抽象方法有什么不同?
一个虚方法必须有一个默认实现,我们可以在派生类中使用 override 关键字来覆盖这个虚方法。抽象方法没有实现,只在抽象类内部创建。在抽象类的情况下,从抽象类派生的类必须具有该抽象方法的实现。下面是一个虚方法的例子:
public class CellPhone { public virtual void Typing() { Console.WriteLine("Using old keypad"); } } public class SmartPhone : CellPhone { public override void Typing() { Console.WriteLine("Using qwerty keyboard"); }}
下面是一个抽象方法的例子:
public abstract class CellPhones { //no default implementation public abstract void Typing(); } public class OldPhones : CellPhones { //function override public override void Typing() { Console.WriteLine("Using keypad"); } } public class SmartPhones : CellPhones { //function override public override void Typing() { Console.WriteLine("Using Qwerty keyboard"); }}
17.什么是方法重载和方法覆盖?
方法重载和覆盖都是一种多态性。
18.什么是static关键字?
我们使用 static 关键字来创建静态类、静态方法或静态属性。当我们创建一个静态类时,该类中只能有静态数据成员和静态方法。静态意味着我们不能创建该类的实例。该类可以像 ClassName.methodName 一样直接使用。当需要其他类的所有实例都具有的特殊功能时,我们使用静态类。例如,需要加载一些默认的应用程序级值。我们创建一个带有静态函数的静态类。然后,所有其他类都可以访问该类,而无需创建任何实例。它还与所有类共享相同的数据。请参考以下示例:
public static class Setting { public static int fetchDefault() { int maxAmount = 0; //code to fetch and set the value from config or some file. return maxAmount; } } public class Sales { //not required to create an instance. int maxAmount = Setting.fetchDefault();}
19.我们可以在静态类中使用“this”吗?
不。“this”不能与静态类一起使用,因为我们只能在静态类中使用静态变量和静态方法。
学习C#课程:Udemy 完整 C# 大师班
https://www.koudaizy.com/tutorials/complete-csharp-masterclass/
20.常量和只读变量有什么区别?
有几点不同:
下面是一个常量示例:
using System;namespace demoapp{ class DemoClass { // Constant fields public const int myvar = 101; public const string str = "staticstring"; // Main method static public void Main() { // Display the value of Constant fields Console.WriteLine("The value of myvar: {0}", myvar); Console.WriteLine("The value of str: {0}", str); } }}
下面是一个只读示例:
using System;namespace demoapp{ class MyClass { // readonly variables public readonly int myvar1; public readonly int myvar2; // Values of the readonly // variables are assigned // Using constructor public MyClass(int b, int c) { myvar1 = b; myvar2 = c; Console.WriteLine("Display value of myvar1 {0}, " + "and myvar2 {1}", myvar1, myvar2); } // Main method static public void Main() { MyClass obj1 = new MyClass(100, 200); } }}
21. C#中的string和string builder有什么区别?
字符串是不可变的对象。当我们必须执行一些操作来更改字符串或附加新字符串时,它会清除字符串对象的旧值,并在内存中创建一个新实例以将新值保存在字符串对象中。例如,它使用 System.String 类。
using System;namespace demoapp{ class StringClass { public static void main(String[] { string val = "Hello"; //creates a new instance of the string val += "World"; Console.WriteLine(val); } }}
StringBuilder 是一个可变对象,这意味着它每次都会为添加字符串(追加),替换字符串(替换)等操作创建一个新实例。它仅将旧对象用于对字符串执行的任何操作,从而提高性能。例如,它使用 System.Text.StringBuilder 类。
using System;using System.Text;namespace demoapp{ class StringClass { public static void main(String[] { StringBuilder val = new StringBuilder("Hello"); val.Append("World"); Console.WriteLine(val); } }}
两个程序的输出都是一样的,“Hello World”。
22.解释“continue”和“break”语句。
我们可以在 C# 的循环中使用 continue 和 break 语句。使用 break 语句,我们可以中断循环执行,而使用 continue 语句,我们可以中断循环的一次迭代。下面是一个 break 语句的例子:
using System;namespace demoapp{ class LoopingStatements { public static void main(String[] args) { for (int i = 0; i <= 5; i++) { if (i == 4) { break; //this will break the loop } Console.WriteLine("The number is " + i); Console.ReadLine(); } //control will jump here after the break statement. } }}
这是带有 continue 语句的相同示例:
using System;namespace demoapp{ class LoopingStatements { public static void main(String[] args) { for (int i = 0; i <= 5; i++) { if (i == 4) { continue;// it will skip the single iteration } Console.WriteLine("The number is " + i); Console.ReadLine(); } } }}
23. 什么是装箱和拆箱?
值类型数据类型到引用类型(对象)数据类型的转换称为装箱。例如:
namespace demoapp{ class Conversion { public void DoSomething() { int i = 10; object o = i; } }}
拆箱是将引用类型数据类型转换为值类型。例如:
namespace demoapp{ class Conversion { public void DoSomething() { object o = 222; int i = (int)o; } }}
24.什么是密封类?
我们使用“sealed”关键字来创建一个密封类。当不需要进一步继承或需要限制该类被继承时,类被创建为密封类。请参阅下面的语法。
public sealed class MyClass{ //properties and methods}
25.什么是偏类?
C# 语言中有一个特性是将单个类文件分成多个物理文件。为此,我们必须使用“partial”关键字。在编译时,它在逻辑上只是一个文件;我们不能在两个不同的分部类文件中拥有同名的方法或同名的变量。 在这里,为了方便开发者将大类文件分解成多个小的物理文件,提供了这个功能。
26.什么是枚举?
“枚举”关键字在许多语言中都很常见。枚举是一种值。它用作相关常量的集合,称为枚举列表。 枚举可以是 int、float、double 或 byte。但如果它不是 int,则需要显式转换。.NET 框架枚举可用于创建数字常量。Int 是枚举元素的默认值。默认情况下,第一个枚举数的值为 0,并且每个后续的枚举数都增加 1,就像一个数组一样。请参考以下语法:enum Day { Sat, Sun, Mon, Tue, Wed, Thu, Fri };
27.什么是依赖注入,如何实现?
依赖注入是一种设计模式。我们不是直接在另一个类(依赖类)中创建一个类的对象,而是将对象作为参数传递给依赖类的构造函数。它有助于编写松散耦合的代码,并有助于使代码更加模块化和易于测试。实现依赖注入的三种方式:
28.请解释“using”语句。
关键字“using”用于定义该 using 语句块中使用的资源的范围。一旦代码块完成执行,在 using 代码块中使用的所有资源都会被释放。请参考以下示例。
class Books : IDisposable { private string _name { get; set; } private decimal _price { get; set; } public Books(string name, decimal price) { _name = name; _price = price; } public void Print() { Console.WriteLine("Book name is {0} and price is {1}", _name, _price); } public void Dispose() { throw new NotImplementedException(); } } class Students { public void DoSomething() { using (Books myBook = new Books("book name", 12.45)) { myBook.Print(); } }}
29.什么是访问修饰符?解释每种类型。
访问修饰符是用于提供对类、成员或函数的可访问性的关键字。以下是它的类型:
访问修饰符的语法:
public class Product{ public void Print() { //code to print something. }}
30.什么是C#委托?
委托就像函数指针,它是一个引用数据类型,保存着方法的引用。我们使用委托来编写泛型类型安全函数。所有委托都派生自 System.Delegate。可以使用 delegate 关键字后跟函数签名来声明委托,如下所示。这些是代表的特征:
请参考以下示例:
using System;namespace demoapp{ class DelegateClass { // declare delegate public delegate void Print(int value); static void Main(string[] args) { // Print delegate points to PrintNumber Print printDel = PrintNumber; // or // Print printDel = new Print(PrintNumber); printDel(100000); printDel(200); // Print delegate points to PrintMoney printDel = PrintMoney; printDel(10000); printDel(200); } public static void PrintNumber(int num) { Console.WriteLine("Number: {0,-12:N0}", num); } public static void PrintMoney(int money) { Console.WriteLine("Money: {0:C}", money); } }}
学习Udemy付费课程:C# 和 .NET 中的设计模式
https://www.koudaizy.com/tutorials/design-patterns-csharp-dotnet/
31.委托有哪些不同类型?
代表分为三种类型:
32.什么是数组?解释一维和多维数组。
该数组存储相同类型的值。它是将变量存储到内存位置的集合。例如:
int[] marks = new int[3] { 25, 34, 89 };
一维数组是线性数组。一维数组将变量存储在一行中。上面的例子是一个一维数组。数组可以有多个维度。多维数组也称为矩形数组。例如:
int[,] numbers = new int[3, 2] { { 1, 2 }, { 2, 3 }, { 3, 4 } };
33. System.Array.CopyTo() 和 System.Array.Clone() 有什么区别?
使用 Clone() 方法,我们可以使用 CopyTo() 方法创建一个包含原始数组的所有元素的新数组对象。现有数组的所有项目都复制到另一个现有数组中。两种方式都会创建一个浅拷贝。
34.Array和ArrayList有什么区别?
Array和 ArrayList 类似。当你想存储相同类型的项目时,可以使用Array。Array具有固定大小。当你要存储任何类型的数据时,我们使用 ArrayList。ArrayList 没有固定大小。参考数组和ArrayList的例子:
using System.Collections;namespace demoapp{ class Sample { //Array and Araraylist. public void ArrayFunction() { string[] country = new string[3]; country[0] = "USA"; //only string value can be added country[1] = "Denmark"; country[2] = "Russia"; //can store different data types ArrayList arraylist = new ArrayList(); arraylist.Add(3); arraylist.Add("USA"); arraylist.Add(false); } }}
35.什么是C#中的交错数组?
交错数组就像一个嵌套数组,其中交错数组的每个元素本身就是一个数组。锯齿状数组的项目可以具有不同的维度和大小。锯齿状数组是 C# 中引入的一种特殊类型的数组。锯齿状数组是数组的数组,其中每个数组索引的长度可以不同。请参考以下示例:
namespace demoapp{ public class JaggedArrayClass { public void ShowJaggedArray() { int[][] jaddedArray = new int[2][]; jaddedArray[0] = new int[3] { 1, 2, 3 }; jaddedArray[1] = new int[4] { 1, 2, 3, 4 }; } }}
36. struct和class有什么区别?
类和结构体都是用户定义的,但有很大的不同。struct 继承自 System.Value 类型,因此它是值类型。当数据量较小时,结构体更可取。结构不能是抽象的。无需使用 new 关键字创建对象。Struct 无权创建任何默认构造函数。结构的语法:
struct MyStruct { public int MyProperty1 { get; set; } public int MyProperty2 { get; set; }}
类是 C# 中的引用类型,它继承自 System.Object 类型。当有大量数据时,使用类。我们可以从另一个类继承一个类。类可以是抽象类型。
37. “throw”和“throw ex”有什么区别?
“throw”语句将保留前一个函数的原始错误堆栈,而“throw ex”语句将保留从抛出点开始的堆栈跟踪。通常,建议使用“throw”,因为它提供了准确的错误信息和跟踪数据。
38.解释“finally”和“finalize block”的区别?
这是两个不同的概念,尽管它们听起来很相似:
因此,finally 与执行处理有关,而 finalize 与垃圾收集有关。
39.解释 var 和 dynamic。
我们可以声明变量的 var 类型,而无需明确指定 .net 数据类型。编译器在编译时根据分配给它的值自动检测变量的类型。我们不能声明一个 var 类型的变量而不给它赋值。var 类型变量的值不能在后面的代码中更改。动态与var相反。
稍后我们可以在代码中更改动态类型变量的值。它还根据分配给它的值决定变量的类型。 就像在创建动态类型的变量时,会为其分配一个整数类型的值,然后在进一步的代码中,我们可以为该变量分配一个字符串类型的值。它保存最后更改的值,其行为类似于它保存的最新值的数据类型。让我们看这个例子来更详细地理解它。
public class Bike { dynamic someValue = 21; public Bike() { //assigned string value later someValue = "Hello"; }}
在上面的示例中,如果我们将变量“someValue”声明为 var 而不是 dynamic,则会引发错误。该错误的原因是在下一行中,我们更改了变量的值并分配了一个字符串值。
高级 C# 编程问题
40. C# 中的匿名类型是什么?
有时我们可能需要创建一个新类型而不定义它。这将被称为匿名类型。当需要在单个对象中定义只读属性而不定义每种类型时,这很有用。 在这里,编译器生成类型并且只能用于当前代码块。请参考以下示例。
public class SomeClass { public void print() { var anonymousData = new { FirstName = "John", SurName = "lastname" }; Console.WriteLine("First Name : " + anonymousData.FirstName); }}
41. 什么是多线程,它有哪些不同的状态?
C# 中的任何代码块都在称为线程的进程中运行。线程是程序的执行路径。简单的应用程序可以在单线程上运行,但今天的程序经常使用多线程。多线程将进程的执行划分为多个线程以同时执行它,从而提高效率。 通过多线程,我们可以一次运行多个任务。程序更高效、更快捷。但是我们还需要了解线程是如何工作的。每个线程都有自己的生命周期,其中包括线程的各种状态:
面向初学者的 C# 编程:第一步
https://www.koudaizy.com/tutorials/c-programming-a-practical-applications-approach/
42. C#中的异常处理是如何完成的?
异常处理通过 try、catch、finally 和 throw 模型进行管理。这些是整个模型中使用的关键字。下面是每个关键字的解释:
下面是异常处理的例子:
public class SomeClass { public void GetData() { try { //write some code here } catch (Exception) { throw; } finally { /*code to execute in the last like dispose objects and resource*/ } } }
43.什么是自定义异常?
自定义异常用于根据用户要求捕获的错误,而不是内置在编译器中的错误。自定义异常是实例化用户定义异常的一种简单方法。请参考以下示例:
public class Purchase{ public void DoPurchase(int quantity) { if (quantity == 0) { //this will throw error here with the custom message throw new Exception("Quantity cannot be zero"); } }}
44.什么是 C# 中的 LINQ?
LINQ 是指语言集成查询。LINQ 是一种使用 .NET 功能和类似于 SQL 的 C# 语法查询数据的方法。 LINQ 的优点是我们可以查询不同的数据源。数据源可以是对象的集合、XML 文件、JSON 文件、内存中的数据或列表或数据库对象。我们可以轻松地从任何实现 IEnumerable<T> 接口的对象中检索数据。下面是 LINQ 的语法。
public class Devices { public void GetData() { List<string> mobiles = new List<string>() { "Iphone","Samsung","Nokia","MI" }; //linq syntax var result = from s in mobiles where s.Contains("Nokia") select s; }}
45.什么是序列化?
当我们想通过网络发送一个对象时,我们必须将该对象转换为字节流。序列化是将对象转换为字节流的过程。为了便于对象进行可序列化,它应该实现 ISerialize 接口。反序列化的过程是从字节流创建对象的逆过程。
46. C#中的泛型是什么?
C# 中的泛型:
使用泛型,我们可以创建集合类。最好使用 System.Collections.Generic 命名空间而不是 System.Collections 命名空间中的类(例如 ArrayList)来创建泛型集合。泛型鼓励使用参数化类型,如下例所示:
using System;namespace demoapp{ //We use < > to specify Parameter type public class GFG<T> { //private data members private T data; //using properties public T value { /using accessors get { return this.data; } set { this.data = value; } } } //vehicle class class Vehicle { //Main method static void Main(string[] args) { //instance of string type GFG<string> company = new GFG<string>(); company.value = "Tata motors"; //instance of float type GFG<float> version = new GFG<float>(); version.value = 6.0F; //display Tata motors Console.WriteLine(company.value); //display 6 Console.WriteLine(version.value); } }}
47.什么是反射(Reflection)?
Reflection 是 C# 中的一个特定类,用于访问程序集或类的元数据。可以使用反射检索以下信息:
48.如何使用可空类型?
空值可以分配给 C# 中的变量。这些类型称为可空类型。大多数变量类型都是可为空的类型。下面的例子:
namespace demoapp{ class Calculate { int? number = null; public Calculate(int num) { number = num; } public void DoCalculation() { if (number.HasValue) { //do something } } }}
49.我们在 C# 中创建的所有类的父类是哪个?
这是一个简单的问题:系统对象。
面向初学者的终极 C# 和 Unity 课程
https://www.koudaizy.com/tutorials/ultimate/
50.解释 C# 中的代码编译。
程序员编写人们可读的代码。然后将该代码输入 C# 编译器。C# 编译器会将代码编译成高效、机器可读的托管代码,称为字节码。然后,即时编译器 (JIT) 会将字节码编译为本机或机器语言。当程序运行时,CPU会直接执行这段代码。
51.什么是 C# 中的哈希表?
哈希表通常包含“键”和“值”。你经常会听到关于密码的“哈希表”;可以为给定的密码创建密码哈希。但是哈希表本身只是键对象和值对象的通用集合,其中的值必须使用键来访问;否则无法访问它们。
52. 如何从基类创建派生类对象?
这是一个技巧问题!你不能。派生类将从基类继承变量和方法。此外,派生类只能有一个基类。你需要直接使用基类进行工作。
53.什么是不可变字符串?
不可变字符串是不能更改的对象,尽管你可以更改对它的引用。通常,只要你有绝对不应该更改的常量,就应该使用不可变字符串。但是,你应该谨慎使用此技巧,因为如果你稍后尝试更改不可变字符串,它可能会引发错误。
54.什么是C#中的反射?
反射是指系统能够查看和修改自身的方法和过程。在 C# 中,反射是指检查系统的内容。它需要通过“System.Reflection”命名空间手动包含在 C# 中。反射对于调试工具特别有用。
55.什么是泛型类?
泛型类是可以处理任何类型的类。这是独一无二的,因为大多数类都遵循严格的类型;你必须声明一个类型,并且该类型必须是一致的。定义一个泛型类如下:
class dataStore<T> { public T data { get; set; }}
56.什么是params关键字,如何使用?
通过使用 params 关键字,你可以指定采用可变数量参数的方法参数。参数类型必须是一维数组。
public static void CalcListSum(params int[] list) { int sum =0 for (int i = 0; i < list.Length; i++) { sum+=list[i]; } Console.WriteLine("The sum is " + sum); }
57. 什么是 NuGet?
NuGet 是面向开发人员的包管理器。它使开发人员能够共享和使用有用的代码。NuGet 包是单个 ZIP 文件,带有 .nupack 或 .nupkg 文件扩展名,并包含 .NET 程序集及其所需文件。
58、什么是DLL文件,使用它们有什么好处?
DLL 是一个库,其中包含可由多个程序同时使用的代码和数据。每个程序都可以使用 DLL 中包含的功能。这有助于提高代码的可重用性和有效的内存使用。通过使用 DLL,可以将程序模块化为单独的组件。
因为模块是分开的,所以程序的加载时间更快。并且仅在请求该功能时才加载模块。此外,更新更容易应用于每个模块,而不会影响程序的其他部分。当这些更改被隔离到 DLL 时,你可以应用更新而无需再次构建或安装整个程序。
59. POCO 是什么意思?
POCO 代表普通旧 CLR 对象。POCO 是一个不依赖于任何特定于框架的基类的类。它与任何其他普通的 .NET 类一样。因此名称为普通旧 CLR 对象。这些 POCO 实体(也称为持久性忽略对象)支持大多数与实体对象派生实体相同的 LINQ 查询。
60. 什么是 DTO?
数据传输对象(通常称为 DTO)通常是 POCO(普通旧 CLR 对象)类的实例,用作封装数据并将其从应用程序的一层传递到另一层的容器。你通常会发现在服务层(后端)中使用 DTO 将数据返回到表示层(前端)。
总结
参考上述问题和答案,可以让我们深入了解 C# 语言的所有基本概念。这些技术性的答案有助于提高我们的知识,并有助于增加我们对语言的理解。如果你需要复习 C#,口袋资源编程训练营或进修课程会有所帮助。
标签: 疯狂答案