.NET面试题

持续整合更新中......

1、值类型和引用类型的区别
      一、值类型
      A、结构体:struct,派生于System.ValueType
           a、数值类型: 整型、浮点型、decimal型
           b、Bool类型
           c、用户定义的结构体
     B、枚举类型:enum,派生于System.Enum
     C、可空类型:派生于System.Nullable泛型结构体,T?实际上是System.Nullable的别名
     二、引用类型
     数组、类、接口、委托、object、字符串
     三、区别
     A、引用类型与值类型相同的是,结构体也可以实现接口;
     B、引用类型可以派生出新的类型,而值类型不能,值类型都是密封(seal)的;
     C、引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型,如 int? a = null);
     D、引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值;
     E、值类型部署在栈上,引用类型部署在托管堆上,引用类型在栈中存储一个引用,其实际的存储位置位于托管堆;
     F、数组的元素不管是引用类型还是值类型,都存储在托管堆上。

2、using的使用方法
     a、引用命名空间、程序集、包
     b、定义命名空间的别名
     c、定义一个范围,在范围结束时处理对象,自动释放所新建的对象,避免缓存、内存溢出,简化try catch

3、new的使用方法
     a、new运算符:用于创建对象和调用构造函数
     b、new修饰符:在用作修饰符时,new关键字可以显式隐藏从基类继承的成员
     c、new约束:用于在泛型声明中约束可能用作类型参数的参数的类型,指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数

4、重写和重载的区别
     a、重写:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法;派生类继承基类的方法,返回类型相同;关键字是override;继承
     c、重载:一个类中的方法与另一个方法同名,但是参数个数或类型不同,这种方法称之为重载方法;返回类型可以不同;多态

5、委托和事件的区别
     a、委托可以把一个方法代入另一个方法,相当于指向函数的指针,换句话说,委托相当于一个函数指针,而事件就相当于保存委托的数组
     b、委托是一个类,该类内部维护着一个字段,指向一个方法;关键字是delegate;public delegate void DoDelegate(string valueStr);
           public delegate void DoDelegate(object sender, EventArgs e);
           void Test(object sender, EventArgs e)
           {
              Console.Write($"valueStr={sender}");
           }
          委托和方法的参数列表一致
     c、调用委托的实例方法Invoke执行方法
     d、事件就是采用委托变量(参数列表)形式执行方法;
           事件是基于委托的,为委托提供一个订阅或发布的机制;
           事件是一种特殊的委托,调用事件和委托是一样的;
           事件的声明方式:public event 委托类型 事件名称;
           事件可以被看作是委托类型的一个变量,通过事件注册、取消多个委托和方法;
           通过+=为事件注册一个或多个委托实例,实际上还可以为事件直接注册方法
     e、委托是一个类,可以实例化,通过委托的构造函数把方法赋值给委托实例;
          触发委托有两种方式:委托实例.Invoke(参数列表)和委托实例(参数列表);
          事件可看作是一个委托类型的变量;
          +=为事件注册多个委托实例或多个方法;
          -=为事件减少多个委托实例或多个方法;
          EventHandler是一个委托。
      f、委托就是事件和方法之间的桥梁
      g、可以直接把一个方法名赋值给委托
      主要区别:
             1.事件只能在方法的外部进行声明,而委托在方法的外部和内部都可以进行声明;
             2.事件只能在类的内部进行触发,不能在类的外部进行触发。而委托在类的内部和外部都可触发;
             3.委托一般用于回调,而事件一般用于外部接口。在观察者模式中,被观察者可在内部声明一个事件作为外部观察者注册的接口。
      系统自带的委托:
             Action委托的非泛型版本就是一个无参数无返回值的委托;
             Action<T>委托的泛型版本是一个无返回值,但是参数个数及类型可以改变的委托;
             Func<T>委托只有泛型版本的,接受参数个数可以是若干个也可以是没有参数,但是一定有返回值,Func<TResult>这个表示没有参数,只有返回值,Func<T,TResult>这个表示有1个参数,有返回值,总之Func委托最后一个TResult表示返回值,前面的不管多少个T都是表示参数。
      委托的使用场景:
             1、事件调用:子窗口向父窗口传值
             2、线程调用:ThreadStart委托;在多线程中的跨线程的方法调用就得用委托
             3、callback回调
             4、LINQ和lambda表达式

6、ref的用法
     a、方法参数无论是值类型,还是引用类型,当在其前加上ref关键字后,对参数的赋值,实际上是改变的是方法参数变量的引用地址
     b、使用带ref的方法之前,需要给方法参变量先声明后赋上初始值
     c、无论是定义方法还是使用方法,都要带上关键字ref

7、out的用法
     a、返回值可有多个(写多个out),不限类型
     b、对out参数传递的变量只需声明,可以赋值也可以不赋值,赋值也会在方法中被覆盖掉
     c、使用out参数传递变量时,必须在方法内为其赋值
     d、方法的参数使用out修饰时,调用该方法时也要加上out关键字
     e、使用out修饰的变量不需要return

8、抽象方法和虚方法的区别
     抽象方法:abstract
         a、只在抽象类中定义,方法修饰符不能使用private、virtual、static
         b、使用派生类对象实例化抽象类
         c、抽象类中的抽象方法必须被子类重写override,与接口类似
         d、抽象方法没有方法体,子类必须重写方法体,因此抽象方法可以看成是一个没有方法体的虚方法
         e、包含抽象方法的类不能被实例化
     虚方法:virtual
         a、虚方法必须有方法体(实现部分)
         b、virtual修饰符不能与private、static、abstract、override修饰符同时使用;override修饰符不能与new 、static、virtual修饰符同时使用
         c、包含虚方法的类可以被实例化
         d、重点是实现多态
     虚函数限制:
         a、虚函数仅适用于有继承关系的类对象,所以只有类的成员函数才能说明为虚函数
         b、静态成员函数、内联函数、构造函数不能是虚函数
         c、析构函数可以是虚函数

9、抽象类和接口的使用
      a、如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本
      b、如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口
      c、如果要设计大的功能单元,则使用抽象类。如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类
      d、抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能

10、泛型的使用
      泛型:是将不确定的类型预先定义下来的一种C#高级语法,我们在使用一个类,接口或者方法前,不知道用户将来传什么类型,或者我们写的类,接口或方法相同的代码可以服务不同的类型,就可以定义为泛型;可以简化代码,便于后期维护。
      泛型是指将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。
      在使用的时候将泛型参数替换成具体的类型,这个过程是在编译的时候进行的,泛型不用拆箱装箱。
      泛型类是指这个类的某些字段的类型是不确定的,只有在构造的时候才能确定下的类,泛型类一般在数据结构中用的比较多,比如 C# 自带的 List<T>,Dictionary<TKey, TValue> 等。
      泛型类可以继承。
      泛型方法是指通过泛型来约束方法中的参数类型,如果没有泛型,每次方法中的参数类型都是固定的,不能随意更改,在使用泛型后,方法中的数据类型则有指定的泛型来约束,即可以根据提供的泛型来传递不同类型的参数。
      泛型接口,可以使用普通类和泛型类实现。
      泛型委托,泛型委托和普通委托差别不大,只是参数由具体类型变成了 "T"。
      泛型约束,对“T” 类型的数据做一定的限制。

11、反射的使用
      程序集包含模块,而模块又包括类型,类型下有成员,反射就是管理程序集,模块,类型的对象,它能够动态的创建类型的实例,设置现有对象的类型或者获取现有对象的类型,能调用类型的方法和访问类型的字段属性。它是在运行时创建和使用类型实例。
      反射的用途:
         a、使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
         b、使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
         c、使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。 
         d、使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
         e、使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
         f、使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
         g、使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
         h、使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

反射的应用场景
     a、获取有关加载的程序集和其中定义的类型的信息
     b、在运行时创建、调用和访问类型实例
     c、访问程序元数据的属性
     d、检查和实例化程序集中的类型
     e、在运行时构建新类型
     f、执行后期绑定,访问在运行时创建的类型的方法

12、this的用法
     a、区分全局变量和局部变量:当变量名同名时,常用在构造函数中;
     b、作为参数传递:方法的参数类型与所在类的类类型一致时,可以直接用this代替类类型;
     c、作为索引器;
     d、调用类中的其他构造函数;
     e、扩展静态类的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值