C# 是最流行的编程语言之一,也是 .NET 开发的首选语言。因此,如果您是一名 .NET 开发人员,正在参加 .NET 面试,您将被问到有关 C# 编程的问题。以下是针对初学者和专业 C# 开发人员的 50 个最佳 C# 面试问题和答案。
41. C# 中的值类型和引用类型是什么?
在 C# 中,数据类型可以分为两种:值类型和引用类型。值类型变量直接包含其对象(或数据)。如果我们将一个值类型变量复制到另一个,我们会为第二个变量复制一份该变量。它们都会独立地对其值进行操作,值类型数据类型存储在堆栈中,而引用数据类型存储在堆中。
在C#中,基本数据类型有int、char、bool、long,这些是值类型,另外类、集合是引用类型。
42. C# 中的序列化是什么?
C# 中的序列化将对象转换为字节流,以将对象存储在内存、数据库或文件中。其主要目的是保存对象的状态,以免在需要时重新创建它。逆向过程称为反序列化。
序列化有三种类型,
- 二进制序列化(将对象数据保存为二进制格式)。
- Soap 序列化(将您的对象数据保存为二进制格式;主要用于网络相关的通信)。
- XmlSerialization(将您的对象数据保存到 XML 文件中)。
43. 如何在 C# 中使用“using”语句?
在 C# 中,using 关键字有两种使用方式。一种是作为指令,另一种是作为语句。让我们来解释一下!
-
using 指令
一般情况下,我们在代码隐藏文件和类文件中添加命名空间时,都会使用 using 关键字,这样当前页面中所有的类、接口、抽象类以及它们的方法和属性都可以使用了。添加命名空间有以下两种方式: -
using 语句
这是在 C# 中使用 using 关键字的另一种方法。它在提高垃圾收集的性能方面起着至关重要的作用。
44. C# 中的锯齿数组是什么?
交错数组是元素为数组的数组。交错数组的元素可以具有不同的维度和大小。交错数组有时被称为“数组的数组”。
C# 中引入了一种特殊类型的数组。交错数组是一种数组的数组,其中每个数组索引的长度可以不同。
例子
int[][] jagArray = new int[5][];
在上面的声明中,行的大小是固定的。但是列没有指定,因为它们可以变化。
声明并初始化锯齿数组。
int[][] jaggedArray = new int[5][];
jaggedArray[0] = new int[3];
jaggedArray[1] = new int[5];
jaggedArray[2] = new int[2];
jaggedArray[3] = new int[8];
jaggedArray[4] = new int[10];
jaggedArray[0] = new int[] { 3, 5, 7, };
jaggedArray[1] = new int[] { 1, 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 1, 6 };
jaggedArray[3] = new int[] { 1, 0, 2, 4, 6, 45, 67, 78 };
jaggedArray[4] = new int[] { 1, 0, 2, 4, 6, 34, 54, 67, 87, 78 };
45. 什么是.NET 的多线程?
多线程允许程序同时运行多个线程。本文介绍了多线程在 .NET 中的工作原理。本文涵盖了线程领域的方方面面,包括线程创建、竞争条件、死锁、监视器、互斥锁、同步、信号量等。
线程的实际用途不是单个顺序线程,而是在单个程序中使用多个线程。多个线程同时运行并执行各种任务称为多线程。线程被视为轻量级进程,因为它在程序上下文中运行并利用为该程序分配的资源。
单线程进程只包含一个线程,而多线程进程则包含多个线程进行执行。
46. C# 中的匿名类型是什么?
匿名类型允许我们创建新类型而无需定义它们。这是一种在单个对象中定义只读属性的方法,而不必明确定义每个类型。在这里,类型由编译器生成,并且只能供当前代码块访问。属性的类型也是由编译器推断的。
我们可以使用“new”关键字和对象初始化器创建匿名类型。
var anonymousData = new
{
ForeName = "Jignesh",
SurName = "Trivedi"
};
Console.WriteLine("First Name : " + anonymousData.ForeName);
LINQ 匿名类型示例
匿名类型还与 LINQ 查询表达式的“Select”子句一起使用来返回属性的子集。
如果任何对象集合具有调用 FirstName、LastName、DOB 等的属性…并且您在查询数据后只想要 FirstName 和 LastName,那么:
class MyData {
public string FirstName {
get;
set;
}
public string LastName {
get;
set;
}
public DateTime DOB {
get;
set;
}
public string MiddleName {
get;
set;
}
}
static void Main(string[] args) {
// Create Dummy Data to fill Collection.
List < MyData > data = new List < MyData > ();
data.Add(new MyData {
FirstName = "Jignesh", LastName = "Trivedi", MiddleName = "G", DOB = new DateTime(1990, 12, 30)
});
data.Add(new MyData {
FirstName = "Tejas", LastName = "Trivedi", MiddleName = "G", DOB = new DateTime(1995, 11, 6)
});
data.Add(new MyData {
FirstName = "Rakesh", LastName = "Trivedi", MiddleName = "G", DOB = new DateTime(1993, 10, 8)
});
data.Add(new MyData {
FirstName = "Amit", LastName = "Vyas", MiddleName = "P", DOB = newDateTime(1983, 6, 15)
});
data.Add(new MyData {
FirstName = "Yash", LastName = "Pandiya", MiddleName = "K", DOB = newDateTime(1988, 7, 20)
});
}
var anonymousData = from pl in data
select new {
pl.FirstName, pl.LastName
};
foreach(var m in anonymousData) {
Console.WriteLine("Name : " + m.FirstName + " " + m.LastName);
}
}
47. C# 中的 Hashtable 是什么?
Hashtable 是存储(键、值)对的集合。在这里,键用于查找存储位置,是不可变的,并且在 Hashtable 中不能有重复的条目。.Net Framework 提供了一个 Hash Table 类,其中包含实现哈希表所需的所有功能,无需任何额外的开发。哈希表是一个通用字典集合。集合中的每个项目都是一个 DictionaryEntry 对象,具有两个属性:一个键对象和一个值对象。这些被称为键/值。将项目添加到哈希表时会自动生成哈希码。此代码对开发人员是隐藏的。使用键对象进行标识可以访问表的值。由于集合中的项目是根据隐藏的哈希码排序的,因此应将项目视为随机排序的。
哈希表集合
基类库提供了在 System.Collections 命名空间中定义的 Hashtable 类,因此您不必编写自己的哈希表。相反,它会处理您每次添加的哈希的每个键,然后使用哈希码快速查找元素。哈希表的容量是哈希表可以容纳的元素数。随着元素添加到哈希表中,容量会根据需要通过重新分配自动增加。它是一种较旧的 .Net Framework 类型。
声明哈希表
Hashtable 类通常位于名为 System.Collections 的命名空间中。因此,要执行任何示例,我们必须将 using System.Collections; 添加到源代码中。Hashtable 的声明为:
Hashtable HT = new Hashtable ();
48. C# 中的 LINQ 是什么?
LINQ 代表语言集成查询。LINQ 是一种数据查询方法,它为 .NET 语言提供与 SQL 查询语法类似的功能。
LINQ 具有查询任何数据源的强大功能。数据源可以是对象集合、数据库或 XML 文件。我们可以轻松地从实现 IEnumerable 接口的任何对象中检索数据。
LINQ 的优点
LINQ 提供了一种基于对象、语言集成的方式来查询数据,无论数据来自何处。因此,通过 LINQ,我们可以查询数据库、XML 和集合。
编译时语法检查。
它允许您使用应用程序的本机语言(例如 VB 或 C#)查询数组、可枚举类等集合,其方式与使用 SQL 查询数据库的方式非常相似。
49. C#.Net 中的文件处理是什么?
System.IO 命名空间提供了四个类,允许您操作单个文件并与机器目录结构交互。Directory 和 File 直接扩展 System.Object,使用各种静态方法支持文件创建、复制、移动和删除。但是,它们只包含静态方法,并且永远不会实例化。FileInfo 和 DirecotryInfo 类型派生自抽象类 FileSystemInfo 类型。它们通常用于获取文件或目录的完整详细信息,因为它们的成员倾向于返回强类型对象。它们实现的公共方法与 Directory 和 File 大致相同,但它们是有状态的,并且这些类的成员不是静态的。
50. C# 中的反射是什么?
反射是运行时类型发现的过程,用于检查元数据、CIL 代码、后期绑定和自生成代码。在运行时,通过使用反射,我们可以访问 ildasm 实用程序在设计时显示的相同“类型”信息。反射类似于逆向工程,我们可以在其中破坏现有的.exe 或.dll 程序集以探索已定义的重要内容信息,包括方法、字段、事件和属性。
使用系统,您可以动态发现给定类型.Reflection 命名空间支持的接口集。
反射通常用于转储已加载的程序集列表、它们对检查方法、属性等的引用。反射还用于外部反汇编工具,如 Reflector、Fxcop 和 NUnit,因为 .NET 工具不需要解析源代码,类似于 C++。
元数据调查
以下程序通过创建基于控制台的应用程序描述了反射的过程。此程序将显示 mscorlib.dll 程序集中任何类型的字段、方法、属性和接口的详细信息。在继续之前,必须导入“System.Reflection”。
这里我们在程序类中定义了几个静态方法来枚举指定类型中的字段、方法和接口。静态方法采用单个“System.Type”参数并返回 void。
static void FieldInvestigation(Type t) {
Console.WriteLine("*********Fields*********");
FieldInfo[] fld = t.GetFields();
foreach(FieldInfo f in fld) {
Console.WriteLine("-->{0}", f.Name);
}
}
static void MethodInvestigation(Type t) {
Console.WriteLine("*********Methods*********");
MethodInfo[] mth = t.GetMethods();
foreach(MethodInfo m in mth) {
Console.WriteLine("-->{0}", m.Name);
}
}