C#.NET 面试题 初级篇(三)
更新: 2023-06-29 18:26:31 字数: 0 字 时长: 0 分钟
IList 接口与 List 的区别是什么?
IList 泛型接口是 Icollection 接口的子代,并且是所有非泛型列表的基接口。 Ilist 实现有三种类别:只读、固定大小、可变大小。 无法修改只读 Ilist。 固定大小的 Ilist 不允许添加或移除元素,但允许修改现有元素。 可变大小的 Ilist 允许添加、移除和修改元素。
IList 是个接口,定义了一些操作方法这些方法要你自己去实现,当你只想使用接口的方法时,这种方式比较好.他不获取实现这个接口的类的其他方法和字段,有效的节省空间.
List 是个类型 已经实现了 IList 定义的那些方法。
泛型的主要约束和次要约束是什么?
当一个泛型参数没有任何约束时,它可以进行的操作和运算是非常有限的,因为不能对实参进行任何类型上的保证,这时候就需要用到泛型约束。泛型的约束分为:主要约束和次要约束,它们都使实参必须满足一定的规范,C#编译器在编译的过程中可以根据约束来检查所有泛型类型的实参并确保其满足约束条件。
1、主要约束:
一个泛型参数至多拥有一个主要约束,主要约束可以是一个引用类型、class 或者 struct。如果指定一个引用类型(class),那么实参必须是该类型或者该类型的派生类型。相反,struct 则规定了实参必须是一个值类型。
2、次要约束
次要约束主要是指实参实现的接口的限定。对于一个泛型,可以有 0 到无限的次要约束,次要约束规定了实参必须实现所有的次要约束中规定的接口。次要约束与主要约束的语法基本一致,区别仅在于提供的不是一个引用类型而是一个或多个接口。
Serializable 特性有什么作用?
在 .NET 中,通过 Serializable 特性提供了序列化对象实例的机制,当一个类型被申明为 Serializable 后,它就能被诸如 BinaryFormatter 等实现了 IFormatter 接口的类型进行序列化和反序列化。
.NET 默认的委托类型有哪几种?
1、Action<T>
泛型 Action 委托表示引用一个 void 返回类型的方法。这个委托类存在 16 种重载方法。
例如 Action<in T1,In T2>调用没有参数的方法
2、Func<T>
Func 调用带返回类型的方法。有 16 种重载方法。
例如 Func 委托类型可以调用带返回类型且无参数的方法,Func<in T,out TResult>委托类型调用带有 4 个参数和一个返回类型的方法。
什么是闭包?
通过 Lambda 表达式可以访问 Lambda 表达式块外部的变量,这成为闭包。
当引用外部变量时,需要注意,外部变量变化时,lambda 表达式的结果也可能会随着外部变量变化而变化。
如何提高 LINQ 性能问题?
提升从数据库中拿数据的速度,可以参考以下几种方法:
1、在数据库中的表中定义合适的索引和键
2、只获得你需要的列(使用 ViewModel 或者改进你的查询)和行(使用 IQueryable)
3、尽可能使用一条查询而不是多条
4、只为了展示数据,而不进行后续修改时,可以使用 AsNoTracking。它不会影响生成的 SQL,但它可以令系统少维护很多数据,从而提高性能
5、使用 Reshaper 等工具,它可能会在你写出较差的代码时给出提醒
什么是协变和逆变?
可变性:
可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用。例如对普通继承中的可变性:若某方法声明返回类型为 Stream,在实现时可以返回一个 MemoryStream。可变性有两种类型:协变和逆变。
协变性:
可以建立一个较为一般类型的变量,然后为其赋值,值是一个较为特殊类型的变量。例如:
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;
因为 string 肯定是一个 object,所以这样的变化非常正常。
逆变性:在上面的例子中,我们无法将 str 和一个新的 object 对象画等号。如果强行要实现的话,只能这么干:
string s = (string) new object();
但这样还是会在运行时出错。这也告诉我们,逆变性是很不正常的。
什么是 IEnumerable?
IEnumerable 及 IEnumerable 的泛型版本 IEnumerable 是一个接口,它只含有一个方法 GetEnumerator。Enumerable 这个静态类型含有很多扩展方法,其扩展的目标是 IEnumerable。
实现了这个接口的类可以使用 Foreach 关键字进行迭代(迭代的意思是对于一个集合,可以逐一取出元素并遍历之)。实现这个接口必须实现方法 GetEnumerator。
IEnumerable 的缺点有哪些?
IEnumerable 功能有限,不能插入和删除。
访问 IEnumerable 只能通过迭代,不能使用索引器。迭代显然是非线程安全的,每次 IEnumerable 都会生成新的 IEnumerator,从而形成多个互相不影响的迭代过程。
在迭代时,只能前进不能后退。新的迭代不会记得之前迭代后值的任何变化。
泛型有哪些常见的约束?
where T :struct //约束 T 必须为值类型
where K : class //约束 K 必须为引用类型
where V : IComparable //约束 V 必须是实现了 IComparable 接口
where W : K //要求 W 必须是 K 类型,或者 K 类型的子类
where X : class,new () // 或者写出 new class() ; X 必须是引用类型,并且要有一个无参的构造函数(对于一个类型有多有约束,中间用逗号隔开)
Collection 和 Collections 的区别?
Collection 是集合类的上级接口
Collections 是针对集合类的一个帮助类,它提供一系列静态方法来实现对各种集合的搜索,排序,线程安全化操作。
五种常见的集合类
1、List:泛型类;
2、Stack:堆栈,后进先出的访问各个元素
3、Dictionary<TKey, TValue>:字典类,key 是区分大小写;value 用于存储对应于 key 的值
4、HashSet:此集合类中不能有重复的子元素
5、SortedList<TKey, TValue>:排序列表,key 是排好序的数组。