面向对象编程从小白到王者系列-C#中的泛型与常见面试题

泛型的地位

泛型在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调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凯杨1319

您的打赏是我持续创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值