泛型的地位
泛型在C#中有很重要的地位,尤其是在搭建项目框架的时候,泛型是C#2.0推出的新语法,是2.0由框架升级提供的功能。
那么什么是泛型,泛型有什么好处,与泛型相关的概念又该怎么使用,比如泛型方法,泛型委托。这一篇我会全面的介绍泛型。
首先我们必须弄清楚什么是泛型,泛型其实也是一种类型,跟我们使用的string,int等一样都是.net的类型。泛型其实就是一个模板类型,万能类型。它允许我们在设计类的时候使用一个类型空白,预留出一个类型。等到我们使用这个类的时候,我们可以使用特定的类型来替换掉我们预留的这个类型,这就是泛型。
泛型能解决的问题
我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但我们没有办法,只能分别写多个方法来处理不同的数据类型。这个时候问题来了有没有一种办法,用同一个方法来处理传入不同种类型参数的办法呢?泛型的出现就是专门来解决这个问题的。
泛型官方定义:泛型是为所存储或使用的一个或多个类型具有占位符(类型形参)的类、结构、接口和方法。
泛型的优点
- 代码的可重用性。无需从基类型继承,无需重写成员。
- 扩展性。
- 类型安全性提高。 泛型将类型安全的负担从你那里转移到编译器。 没有必要编写代码来测试正确的数据类型,因为它会在编译时强制执行。 降低了强制类型转换的必要性和运行时错误的可能性。
- 性能提高。泛型集合类型通常能更好地存储和操作值类型,因为无需对值类型进行装箱。
定义和使用泛型
在我们讨论泛型的优点的时候,先来看看怎么使用泛型,泛型一般与集合一起使用。
语法如下(学习编程必须掌握语法,没有其他方法,只能通过练习记住各种语法的使用):
public class Generic<T>
{
public T Field;
}
注意:我们在声明泛型T的时候,并不是一定类型名是T,T是在一个类型的时候,如果我们需要使用多个泛型来实例化一个类型,那么我们就需要使用说明性的名称,比如TId,TFirstName之类的。
案例如下:
public class Person<T>
{
private T _t;
public T T1
{
get { return _t; }
set { _t = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public Person() { }
public Person(T t1, string name)
{
this._t = t1;
this._name = name;
}
}
上述代码的调用方法:
//传入整数类型
Person<int> person = new Person<int>(1, "曹操");
//传入字符串类型
Person<string> personString = new Person<string>("001", "曹操");
上述案例就是泛型的代码的可重用性。
接下来我们扩展一个类,来看看泛型的扩展性,我们可以扩展Person<T>中的T,在任何时候,如果需求发生了变化,增加了证件号。我们就能在不改变Person类的情况下扩展出证件号。
public class MyCardId
{
private string _number;
public string Number
{
get { return _number; }
set { _number = value; }
}
public MyID() { }
public MyID( string number)
{
this._number = number;
}
}
我们扩展了一个MyCardId类,这里我们不需要更改Person类就可以直接扩展出了Number了。因为Person<T>中的T是可以使用任何类型来替换的。
MyCardId mycardId =new MyCardId ("0001");
Person<MyCardId > personID = new Person<MyCardId >(mycardId , "曹操");
Console.WriteLine("Number:{0},Name:{1}",myId.Number,personID.Name);
这样就扩展了Person类。
关于性能和安全性这里就不详细讲解了,大家知道泛型有这两个有点就行了。
接下来给大家整理了一些.net的常见面试问题,希望对大家有帮助。
问题:描述一下C#中索引器的实现过程,是否只能根据数字进行索引
答:
C#通过提供索引器,可以象处理数组一样处理对象。特别是属性,每一个元素都以一个get或set方法暴露。索引器不单能索引数字(数组下标),还能索引一些HASHMAP的字符串,所以,通常来说,C#中类的索引器通常只有一个,就是THIS,但也可以有无数个,只要你的参数列表不同就可以了索引器和返回值无关, 索引器最大的好处是使代码看上去更自然,更符合实际的思考模式。索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。
问题:什么是装箱和拆箱?
答:
装箱就是隐式的将一个值型转换为引用型对象。
拆箱就是将一个引用型对象转换成任意值型。
string i=“aaa”;
System.Object obj=i; //这个过程就是装箱!就是将 i 装箱!
string j=(string)obj;//这个过程 obj 拆箱!
问题:在.net中,配件的意思是?
答:程序集。(中间语言,源数据,资源,装配清单)
问题:在C#中,string str1 = null 与 string str2 =""请尽量使用文字或图象说明其中的区别
答:string str1 = null 是不给他分配内存空间,而string str2 = "" 给它分配长度为空字符串的内存空间,因此str1还不是一个实例化的对象,而str2已经实例化
注意null不是对象,""是对象
问题:abstract class和interface有什么区别?
答:
- abstract class
abstract 声明抽象类抽象方法,一个类中有抽象方法,那么这个类就是抽象类了。所谓的抽象方法,就是不含主体(不提供实现方法),必须由继承者重写。因此,抽象类不可实例化,只能通过继承被子类重写。
- interface
声明接口,只提供一些方法规约,不提供任何实现;不能用public、abstract等修饰,无字段、常量,无构造函数 -
区别
1.interface中不能有字段,而abstract class可以有;
2.interface中不能有public等修饰符,而abstract class 可以有。
3.interface 可以实现多继承
问题:try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
答:会执行,在return前执行。
问题:进程和线程的区别?
答:进程是系统进行资源分配和调度的单位;
线程是CPU调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。