.net(2)

11.interface是否可继承interface?abstract class 是否可实现interface

回答1:接口能够继承接口,并且能够继承多个接口,用“,”进行分割,接口不容许直接或间接地从自身继承。和类的继承类似,接口的继承也造成接口之间的层次结构javascript

回答2:抽象类是能够实现接口的,抽象类里能够有抽象方法,也能够有具体的实现方法,也就是说继承了接口后也是能够实现接口里定义的方法
参考文章:html

  1. C#之接口

12.private、protected、public、internal

修饰访问符这个算是挺基础的了,不过也不能忘记哦前端

  1. public:同一程序集中的任何其余代码或引用该程序集的其余程序集均可以访问该类型或成员。
  2. private:只有同一类或结构中的代码能够访问该类型或成员。
  3. protected:只有同一类或结构或者此类的派生类中的代码才能够访问的类型或成员。
  4. internal:同一程序集中的任何代码均可以访问该类型或成员,但其余程序集中的代码不能够。
  5. protected internal:由其声明的程序集或另外一个程序集派生的类中任何代码均可访问的类型或成员。 从另外一个程序集进行访问必须在类声明中发生,该类声明派生自其中声明受保护的内部元素的类,而且必须经过派生的类类型的实例发生。

参考文章:
1.访问修饰符(C# 编程指南)java

13.asp.net中 static的存活周期

全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另外一块区域。 当类首次被加载时static定义的变量被分配空间,程序结束后由系统释放.
若是在一个程序里过多的使用static定义的成员,确实很占内存,由于他的生命周期是整个程序,程序运行时没法被gc所回收,直到程序结束,释放内存.jquery

参考文章:web

1.静态类和静态类成员(C# 编程指南)面试

14.try{}里有一个return语句,那么紧跟 在这个try后的finally{}里的代码会不会被执行,是在return前仍是后

这题我tm面试的几间都有啊,公司得有多懒sql

答案:会执行,在return后执行数据库

15.new的做用,where的做用

  1. new 运算符:用于建立对象和调用构造函数。
  2. new 修饰符:用于向基类成员隐藏继承成员。
  3. new 约束:用于在泛型声明中约束可能用做类型参数的参数的类型。

参考文章:编程

  1. new(C# 参考)
  2. C# where用法

    16.this的做用

    this 关键字引用类的当前实例,还可用做扩展方法的第一个参数的修饰符。

用途:

  1. 限定被类似的名称隐藏的成员,例如
public Employee(string name, string alias) { // Use this to qualify the fields, name and alias: this.name = name; this.alias = alias; }
  1. 将对象做为参数传递到其余方法,例如
CalcTax(this); 
  1. 声明索引器,例如:
public int this[int param] { get { return array[param]; } set { array[param] = value; } }

参考文章:
this(C# 参考)

17.MVC的各个部分用什么技术实现,和三层架构的关系

这个要详细讲的话得要一本书吧,我就说大概。ASP.NET MVC包含了三部分,Model,View和Controller。Controller负责后台逻辑代码,View是纯净的HTML页面,Model是中间数据层。

1.概述

  • 当咱们讨论系统时,它通常包含用户输入逻辑、业务处理逻辑以及UI显示逻辑等,MVC是一种架构模式,它可以让咱们开发出各个模块之间松耦合的应用程序。MVC最主要的目的是“关注点分离”,它可以分离开UI显示、业务逻辑以及用户输入等。根据MVC的规定,一个系统应该被划分为Model、View以及Controller三个部分
  1. Model:它被当作一个能够处理业务规则、逻辑以及数据的智能体,同时它独立于MVC中其它两个部分(C和V)(不访问Controller和View,译者注)
  2. Controller:它负责接收用户请求、分配请求给处理者,它能够访问Model和View。
  3. View:它被当作一个哑吧,专门呈现最终的数据给用户。它能够是一个excel表单,也能够是一个包含许多记录的web页面甚至是一个纯文本。它能够访问Model。

2.MVC与三层架构的区别

①.各自原理

前提固然是要搞懂这二者的联系了

三层架构是最基本的项目分层结果,而MVC则是三层架构的一个变体,MVC是一种好的开发模式。
首先你要明白MVC分别表明的是什么意思.

  1. M 即Model(模型层),主要负责出来业务逻辑以及数据库的交互
  2. V 即View(视图层),主要用于显示数据和提交数据
  3. C 即Controller(控制器),主要是用做捕获请求并控制请求转发

三层:UI 界面层 BLL 业务逻辑层,DAL数据访问层,Model 实体层
MVC中的的M 不是三层中的Model(实体层),他其实包括三层中的 BLL,DAL,Model,这是很是要注意的,这也是他们之间的区别的关键所在

三层是基于业务逻辑来分的,而mvc是基于页面来分的

MVC是 Model-View-Controller,严格说这三个加起来之后才是三层架构中的WEB层,也就是说,MVC把三层架构中的WEB层再度进行了分化,分红了控制器、视图、实体三个部分,控制器完成页面逻辑,经过实体来与界面层完成通话;而C层直接与三层中的BLL进行对话

②.区别之处

  • 在三层中也提到了Model,可是三层架构中Model的概念与MVC中Model的概念是不同的,“三层”中典型的Model层是已实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。
  • 首先,MVC和三层架构,是不同的。
    三层架构中,DAL(数据访问层)、BLL(业务逻辑层)、WEB层各司其职,意在职责分离。
      MVC是 Model-View-Controller,严格说这三个加起来之后才是三层架构中的WEB层,也就是说,MVC把三层架构中的WEB层再度进行了分化,分红了控制器、视图、实体三个部分,控制器完成页面逻辑,经过实体来与界面层完成通话;而C层直接与三层中的BLL进行对话。因此, .net的三层结构中,并无action这个概念。
  • MVC模式是一种复合设计模式,一种解决方案;三层是种软件架构,经过接口实现编程
  • 三层模式是体系结构模式,MVC是设计模式
  • 三层模式又可归于部署模式,MVC可归于表示模式

参考文章:

  1. 7 天玩儿 转 ASP.NET MVC
  2. WebForms VS. MVC(翻译)
  3. mvc与三层结构终极区别

18.MVC框架中能够实现AOP效果的接口是?

关于AOP,它面向的是一个切面,可以把公共的功能抽出来,独立开发,而后将公共部分实现,在开发人员不知情的状况下,添加进去。而在MVC前台框架中,MVC中Controller中的Filter能够将公共的代码抽离出来。

实现AOP效果的接口(只列举经常使用)

Asp.Net MVC提供了如下几种默认的Filter:

Filter Type 实现接口 执行时间 Default Implementation
Authorization filter IAuthorizationFilter 在全部Filter和Action执行以前执行 AuthorizeAttribute
Action filter IActionFilter 分别在Action执行以前和以后执行。 ActionFilterAttribute
Result filter IResultFilter 分别在Action Result执行以后和以前 ResultFilterAttribute
Exception filter IExceptionFilter 只有在filter,或者 action method, 或者 action result 抛出一个异常时候执行 HandleErrorAttribute

参考文章:

  1. MVC过滤器 实现AOP(入门)
  2. ASP.NET MVC3 类面向切面AOP 的Filter操做

19.Entity Framework是什么

1.Entity Framework简述

微软官方提供的ORM工具,ORM让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上。EF提供变动跟踪、惟一性约束、惰性加载、查询事物等。开发人员使用Linq语言,对数据库操做如同操做Object对象同样省事。

EF有三种使用场景,

  1. 从数据库生成Class
  2. 由实体类生成数据库表结构,
  3. 经过数据库可视化设计器设计数据库,同时生成实体类。

ORM 是什么?

ORM 是将数据存储从域对象自动映射到关系型数据库的工具。ORM主要包括3个部分:域对象、关系数据库对象、映射关系。ORM使类提供自动化CRUD,使开发人员从数据库API和SQL中解放出来。

EntityFramework 架构

image

  • EDM (实体数据模型):EDM包括三个模型,概念模型、 映射和存储模型。
  • 概念模型 ︰ 概念模型包含模型类和它们之间的关系。独立于数据库表的设计。
  • 存储模型 ︰ 存储模型是数据库设计模型,包括表、 视图、 存储的过程和他们的关系和键。
  • 映射 ︰ 映射包含有关如何将概念模型映射到存储模型的信息。
  • LINQ to Entities ︰ LINQ to Entities 是一种用于编写针对对象模型的查询的查询语言。它返回在概念模型中定义的实体。
  • Entity SQL: Entity SQL 是另外一种炉相似于L2E的言语,但相给L2E要复杂的多,因此开发人员不得不单独学习它。
  • Object Services(对象服务):是数据库的访问入口,负责数据具体化,从客户端实体数据到数据库记录以及从数据库记录和实体数据的转换。
  • Entity Client Data Provider:主要职责是将L2E或Entity Sql转换成数据库能够识别的Sql查询语句,它使用Ado.net通讯向数据库发送数据可获取数据。
  • ADO.Net Data Provider:使用标准的Ado.net与数据库通讯

DBContext

DbContext是EntityFramework很重要的部分,链接域模型与数据库的桥梁,是与数据库通讯的主要类。
image

DbContext主要负责如下活动:

  • EntitySet::DbContext包含了全部映射到表的entities
  • Querying:将Linq-To-Entities转译为Sql并发送到数据库
  • Change Tracking:从数据库获取entities后保留并跟踪实体数据变化
  • Persisting Data:根据entity状态执行Insert、update、delete命令
  • Caching:DbContext的默认第一级缓存,在上下文中的生命周期中存储entity
  • Manage Relationship:DbContext在DbFirst模式中使用CSDL、MSL、SSDL管理对象关系,Code first中使用fluent api 管理关系
  • Object Materialization:DbContext将物理表转成entity实例对象

参考文章:

  1. Entity Framework 基础

20.entityframework的开发模式

简述

有三种方式:Code First、DBFirst、Model First

  1. CodeFirst 领域设计时先定义实体类,用实体类生成数据库
  2. DbFirst 从数据库生成实体类
  3. Model First 使用Visual Studio实体设计器,设计ER,同时生成Entity类和DB

查询方式

  1. LINQ to Entities:
//Querying with LINQ to Entities using (var context = newSchoolDBEntities()) { var L2EQuery = context.Students.where(s => s.StudentName == "Bill"); var student = L2EQuery.FirstOrDefault<Student>(); } LINQ Query syntax: using (var context = new SchoolDBEntities()) { var L2EQuery = from st in context.Students where st.StudentName == "Bill"select st; var student = L2EQuery.FirstOrDefault<Student>(); }
  1. Entity SQL
//Querying with Object Services and Entity SQL string sqlString = "SELECT VALUE st FROM SchoolDBEntities.Students " + "AS st WHERE st.StudentName == 'Bill'"; var objctx = (ctx as IObjectContextAdapter).ObjectContext; ObjectQuery<Student> student = objctx.CreateQuery<Student>(sqlString); Student newStudent = student.First<Student>(); //使用EntityDataReader using (var con = newEntityConnection("name=SchoolDBEntities")) { con.Open(); EntityCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT VALUE st FROM SchoolDBEntities.Students as st where st.StudentName='Bill'"; Dictionary<int, string> dict = newDictionary<int, string>(); using (EntityDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)) { while (rdr.Read()) { int a = rdr.GetInt32(0); var b = rdr.GetString(1); dict.Add(a, b); } } }
  1. Native SQL
using (var ctx = newSchoolDBEntities()) { var studentName = ctx.Students.SqlQuery("Select studentid, studentname, standardId from Student where studentname='Bill'").FirstOrDefault<Student>(); }

1.请从中选择引用类型或值类型

提及题,咱们不禁得会想到几个名词:栈和堆,值类型和引用类型,装箱和拆箱。

这些概念但是C#的入门基础呀,我们仍是要搞懂的,详细能够查看参考文章。

这里要提下一个知识点:C#新手都有一个误区:值类型的值都是保存在栈里,实际应该是:值类型的值是在它声明的位置存储的。即局部变量(参数)的值会在栈里,而当值类型做为引用类型的类型成员的话,会跟随对象,即存储在托管堆里。

顺便提供几张经典图片便于读者理解:

image

image

最后在这些概念里,我以为比较重要的精华提要:

  1. 对于栈和堆的概念,咱们声明值类型和引用类型的时候,为何会分配两种内存而不是一种呢?只要咱们仔细想一下,基本类型他们并不复杂,不少时候只包含简单的值,好比 i=1,而对象类型则相对复杂,它们则会引用其余对象或基本类型。简单来讲,对象类型须要动态内存而基本类型则须要静态内存。若须要分配动态内存,那么就分配到堆上;反之在栈上。
  2. 对于值类型和引用类型的概念,值类型,它们的内存值都分配在栈上,当咱们把一个int值分配给另一个int值时,须要建立一个彻底不一样的拷贝。换句话说,你能够改变其中任何一个而不会影响另一个。这种数据类型被称为值类型;引用类型,当咱们建立一个对象,并把一个对象赋给另一个对象时,它们的指针指向相同的内存(以下图,当咱们把obj赋给obj1时,它们指向相同的内存)。换句话说,咱们改变其中一个,会影响到另一个。

参考文章

  1. 图解C#的值类型,引用类型,栈,堆,ref,out
  2. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱强烈推荐此篇文章
  3. .NET下的内存分配机制
  4. 从栈和堆中来看值传递和引用传递

2.判断一个string变量是否为空

最普通的用法固然就是:

  • s.Length == 0
  • s == string.Empty
  • s == ""

效率上:s.Length == 0 > s == string.Empty > s == ""

不过 net 2.0后,可用String.IsNullOrEmpty(s) 来进行判断

参考文章

String.IsNullOrWhiteSpace和String.IsNullOrEmpty的区别

3.Lock的做用

关于lock的介绍就到这里,有下面几点须要注意的地方

  1. lock的是引用类型的对象,string类型除外。
  2. lock推荐的作法是使用静态的、只读的、私有的对象。
  3. 保证lock的对象在外部没法修改才有意义,若是lock的对象在外部改变了,对其余线程就会畅通无阻,失去了lock的意义。

还有摘自本篇评论的精彩回复:

this 表示的就是当前实例,当你再new一个的时候,锁定的就再也不是同一个对象了。 不能锁定值类型的缘由是,当这个值类型传递到另外一个线程的时候,会建立一个副本,锁定的也再也不是同一个对象了。 锁定字符串带来的问题是,字符串在CLR中会暂存在 内存中,若是有两个变量被分配了相同的字符串内容,那么这两个引用会指向同一块内存,实际锁定也就是同一个对象,这就会致使整个应用程序的阻塞。因此锁定字符串是很是危险的行为。

参考文章:

1.[C#基础]说说lock到底锁谁?](http://www.cnblogs.com/wolf-sun/p/4209521.html)

4.abstract class 和 interface 有什么区别

这篇已经有提过了:请参阅:最近找工做面的面试题目汇总(一)

5.关键字params是什么

参考文章:

为了将方法声明为能够接受可变数量参数的方法,咱们可使用params关键字来声明数组

要求:

  1. 在方法声明中的 params 关键字以后不容许任何其余参数,而且在方法声明中只容许一个 params 关键字
  2. 该参数必须标识一个一维数组,但类型不限,对该参数传递null或者0个数目的数组的引用都是合法的

参考文章:

  1. C# 参数关键字params
  2. C#中的params关键字的用法

6.怎么获取用户请求的Url地址

  1. 获取 完整url:
string url=Request.Url.ToString(); 

参考文章:

  1. asp.net获取当前网址url

写出三元运算符实例

这个我就不说了。 ?:

7.说明Stack和Queue的区别

1.Queue的定义

Queue是先进先出(first in first-out)数据结构,表示放进queue的第一个数据,会是第一个拿出来使用

示例:

//创建Queue的对象 var myqueue = new Queue<string>(); //新增数据进入queue myqueue.Enqueue("第1个"); myqueue.Enqueue("第2个"); myqueue.Enqueue("第3个"); //查看queue的全部资料 foreach (string queue in myqueue) { Console.WriteLine(queue); } //使用Peek()方法查看queue里的第一条数据 Console.WriteLine(""); Console.WriteLine("使用peek方法的輸出值:" + myqueue.Peek()); //使用Dequeue()方法从queue中拿出值 //记得是先进先出的获取方法 Console.WriteLine("第一个被我拿走了:" + myqueue.Dequeue()); //查看剩下的值 Console.WriteLine("查看myqueue剩下的值"); foreach (string queue in myqueue) { Console.WriteLine(queue.ToString()); } //查看某位置的值 Console.WriteLine("查看特定位置的值"); Console.WriteLine(myqueue.ElementAt(1));

运行结果

第1个
第2个
第3个

使用peek方法的輸出值:第1个 第一个被我拿走了:第1个 查看myqueue剩下的值 第2个 第3个 查看特定位置的值 第3个 第3个 第2个 第1个 Peek看到的数据:第3个 被拿走了:第3个 查看剩下的数据 第2个 第1个

2.Stack的定义

Stack为后进先出(first-in last-out)的数据结构,表示第一个进去的数据,反而是最后一个出来。

示例代码

//创建Stack对象 var mystack = new Stack<string>(); //插入数据 mystack.Push("第1个"); mystack.Push("第2个"); mystack.Push("第3个"); //查看数据 foreach(string stack in mystack) { Console.WriteLine(stack.ToString()); } //Stack与Queue同样有Peek方法查看第一条数据 Console.WriteLine(""); Console.WriteLine("Peek看到的数据:"+mystack.Peek()); //使用Pop方法取出数据 Console.WriteLine("被拿走了:"+mystack.Pop()); Console.WriteLine("查看剩下的数据"); foreach (string stack in mystack) { Console.WriteLine(stack.ToString()); }

运行结果

第3个
第2个
第1个

Peek看到的数据:第3个
被拿走了:第3个
查看剩下的数据
第2个
第1个

参考文章:

1..NET源码Stack和Queue的实现

2.C#資料群集系列菜單-『Queue與Stack』

8.Overload和Override的区别

1.Overload的定义

重载应该叫overload,重载某个方法是在同一个类或父子关系类中发生的!重载(overload)是提供了一种机制, 相同函数名经过不一样的返回值类型以及参数来表来区分的机制

overload:  同一类中或父子关系类中皆可.
                   public string ToString(){return "a";} public string ToString(int id){return id.ToString();}

2.Override的定义

重写叫override,重写是在子类中重写父类中的方法。重写(override)是用于重写基类的虚方法,这样在派生类中提供一个新的方法

override: 父类:public virtual string ToString(){return "a";} 子类:public override string ToString(){return "b";}

3.二者间的区别

很本质的区别就是看函数特征:覆写(Override)的两个函数的函数特征相同,重载(Overload)的两个函数的函数名虽然相同,但函数特征不一样。

  1. override 是在继承的时候,若是你写的函数与要继承的函数函数特征相同,那么,加上这个关键字,在使用这个子类的这个函数的时候就看不见父类(或超类)的函数了,它被覆盖掉了。
    好比:Derived继承了Base,Base里面有void A(int a) ,那么若是你Derived里面以为A写得很差或不适合这个类,你想从新再写一遍A里的代码,那么就写override void A(int a)这样,原来的那个函数就被你新写的这个覆盖掉了。
    overload 是重载,就是说函数名相同,函数特征不一样,系统会根据你提供的参数来调相应的函数。好比:void A(int a)和void A(int a,int b) ,若是你用的是A(1)那么调的是第一个,若是是A(1,1)那么调的是第二个。

参考文章:

  1. C#中override和overload的区别

## 9. using的意义
简述:

提供能确保正确使用 IDisposable 对象的方便语法。它的用途就是清理非托管资源,不受GC控制的资源。Using结束后会隐式的调用Disposable方法

  1. 有许多其余类别的非托管资源和封装这些资源的类库类型,全部这些类型都必须实现IDisposable接口,而using语句确保即便在调用对象上的方法时发生异常Dispose方法也会被调用。
  2. 实际上,将对象放入 try 块中并在finally块中调用Dispose同样能够达到一样的效果,而这功能就是编译器转换using语句的方式。

如下两段代码的做用是一致的

using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; }
{
  Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); } }

参考文章:

  1. using 语句(C# 参考)
  2. 三种C# using的用法

    10.List是什么

    由于ArrayList存在不安全类型与装箱拆箱的缺点,因此出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList类似,由于List类也继承了IList接口。最关键的区别在于,在声明List集合时,咱们同时须要为其声明List集合内数据的对象类型。

优势

  1. 类型安全
  2. 性能加强
  3. 代码服用

1.抽象类的介绍,抽象类里的虚函数和抽象函数

参考文档

  1. 抽象类、密封类及类成员(C# 编程指南)
  2. abstract(C# 参考)

    简介

    不能初始化的类被叫作抽象类,它们只提供部分实现,可是另外一个类能够继承它而且能建立它们
    的实例。抽象类可以被用于类,方法,属性,索引器和事件,使用abstract 在一个类声明中表示该类倾向要做为其它类的基类,成员被标示成abstract,或被包含进一个抽象类,必须被其派生类实现。

  3. 一个抽象类能够包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现全部的,一个抽象方法是一个没有方法体的方法。
  4. 经过声明派生类也为抽象,咱们能够避免全部或特定的虚方法的实现,这就是抽象类的部分实现。
  5. 在C#中,一个抽象类可以继承另外一个非抽象类,另外,继承了基类的方法,添加新的抽象和非抽象方法是可行的。
  6. 一个抽象类也能从一个接口来实现,这种状况,咱们必须为全部的方法提供方法体,这些方法是来自接口。
  7. 咱们不能把关键字abstract 和 sealed 一块儿用在C#中,由于一个密封类不可以被抽象。
  8. 一个抽象类必须为全部的接口成员提供实现

一个用于实现接口的抽象类可能把接口方法安排到抽象方法上。例如

interface I { void M(); } abstract class C: I { public abstract void M(); }

抽象类特征

  1. 抽象类不能被实例化;
  2. 抽象类能够包含抽象方法和访问器;
  3. 不能把抽象类用密封(sealed)来修饰,那就意味着类不能被继承,这违反抽象类被继承的原则;
  4. 一个派生于一个抽象类的非抽象类必须包括全部的继承来的抽象方法和访问器的实现;
  5. 在方法和属性中使用abstract 关键字意味着包含它们的实现

抽象方法特征

  1. 抽象方法是隐式的虚方法;
  2. 抽象方法的声明只能在抽象类中;
  3. 由于抽象方法声明只提供一个无实现的方式,没有方法体;
  4. 方法体的实现被覆写方法提供,覆写方法是一个非抽象类的成员;
  5. 抽象属性的行为和抽象方法相像,除了不一样的声明形式。
  6. 在一个静态属性中使用abstract 是一个错误。
    *一个抽象属性可以经过派生类使用 override 实现.

2.虚函数和抽象方法

 

参考文档

  1. C#之虚函数
  2. 虚方法(virtual)和抽象方法(abstract)的区别

    虚方法与非虚方法的最大不一样是,虚方法的实现能够由派生类所取代,这种取代是经过方法的重写实现的。

虚方法的特色

  1. 虚方法前不容许有static,abstract,或override修饰符;
  2. 虚方法不能是私有的,所以不能使用private修饰符;
  3. 咱们知道通常函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,而虚函数在编译期间是不被静态编译的,它的相对地址是不肯定的,它会根据运行时期对象实例来动态判断要调用的函数,
    其中那个申明时定义的类叫申明类,那个执行时实例化的类叫实例类
    如:A a =new B(); 其中A是申明类,B是实例类。
  • 当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;
  • 若是不是虚函数,那么它就直接执行该函数。而若是是一个虚函数,那么这个时候它就不会马上执行该函数了,而是开始检查对象的实例类。
  • 在这个实例类里,他会检查这个实例类的定义中是否有实现该虚函数或者从新实现该虚函数(经过override关键字)的方法,若是有,它就不会再找了,而是立刻执行该实例类中实现的虚函数的方法。而若是没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,而后执行该父类里重载后的函数。
 

虚方法(virtual)和抽象方法(abstract)的区别

  1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,不然派生类将不能被实例化。如:
//抽象方法 public abstract class Animal { public abstract void Sleep(); public abstract void Eat(); } //虚方法 public class Animal { public virtual void Sleep(){} public virtual void Eat(){} }
  1. 抽象方法只能在抽象类中声明,虚方法不是。其实若是类包含抽象方法,那么该类也是抽象的,也必须声明为抽象的。如:
public class Animal { public abstract void Sleep(); public abstract void Eat(); } 

编译器会报错:
Main.cs(10): 'VSTest.Animal.Sleep()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
Main.cs(11): 'VSTest.Animal.Eat()' is abstract but it is contained in nonabstract class 'VSTest.Animal'

  1. 抽象方法必须在派生类中重写,这一点跟接口相似,虚方法没必要。
public abstract class Animal { public abstract void Sleep(); public abstract void Eat(); } public class Cat : Animal { public override void Sleep() { Console.WriteLine( "Cat is sleeping" ); } // we need implement Animal.Eat() here }

编译器会报错:Main.cs(14): 'VSTest.Cat' does not implement inherited abstract member 'VSTest.Animal.Eat()'
由于咱们没有实现抽象类中全部抽象方法。

3.静态类和静态类成员

 

参考文档

  1. 静态类和静态类成员(C# 编程指南)
  2. C#静态方法与非静态方法的比较

(一).C#静态方法与非静态方法比较1、C#静态成员

  • 静态成员属于类全部,非静态成员属于类的实例全部。
  • 每建立一个类的实例,都会在内存中为非静态成员新分配一块存储;非静态成员属于类全部,为各个类的实例所公用,不管类建立了多少实例;类的静态成员在内存中只占同一块区域。
 

(二).C#静态方法与非静态方法比较2、C#静态方法

  • C#静态方法属于类全部,类实例化前便可使用。
  • 非静态方法能够访问类中的任何成员,静态方法只能访问类中的静态成员
  • 由于静态方法在类实例化前就可使用,而类中的非静态变量必须在实例化以后才能分配内存,这样,C#静态方法调用时没法判断非静态变量使用的内存地址。因此没法使用。而静态变量的地址对类来讲是固定的,故可使用。
 

(三).C#静态方法与非静态方法比较3、C#静态方法是一种特殊的成员方法

它不属于类的某一个具体的实例,而是属于类自己。因此对静态方法不须要首先建立一个类的实例,而是采用类名.静态方法的格式 。

  • static方法是类中的一个成员方法,属于整个类,即不用建立任何对象也能够直接调用!

    static内部只能出现static变量和其余static方法!并且static方法中还不能使用this....等关键字..由于它是属于整个类!

  • 静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则能够作销毁。
  • 静态方法和静态变量建立后始终使用同一块内存,而使用实例的方式会建立多个内存.
  • C#中的方法有两种:实例方法,静态方法.

 

(四).C#静态方法与非静态方法比较4、C#静态方法中获取类的名称

静态方法中用:

string className = System.Reflection.MethodBase. GetCurrentMethod().ReflectedType.FullName; 

非静态方法中还能够用:

string className = this.GetType().FullName; 

4.静态构造函数

定义:静态构造函数用于初始化任何 静态 数据,或用于执行仅需执行一次的特定操做。 在建立第一个实例或引用任何静态成员以前,将自动调用静态构造函数。

静态构造函数具备如下特色:

  1. 静态构造函数既没有访问修饰符,也没有参数。
  2. 在建立第一个实例或引用任何静态成员以前,将自动调用静态构造函数来初始化类。
  3. 没法直接调用静态构造函数。
  4. 在程序中,用户没法控制什么时候执行静态构造函数。
  5. 静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项。
  6. 静态构造函数在为非托管代码建立包装类时也颇有用,此时该构造函数能够调用 LoadLibrary 方法。
  7. 若是静态构造函数引起异常,运行时将不会再次调用该构造函数,而且在程序运行所在的应用程序域的生存期内,类型将保持未初始化。

5.接口和抽象类

参考文档

  1. C#中抽象类和接口的区别

①.抽象类和接口的区别:

  1. 类是对对象的抽象,能够把抽象类理解为把类看成对象,抽象成的类叫作抽象类.而接口只是一个行为的规范或规定,微软的自定义接口老是后带able字段,证实其是表述一类类“我能作。。。”。抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
  2. 接口基本上不具有继承的任何具体特色,它仅仅承诺了可以调用的方法;
  3. 一个类一次能够实现若干个接口,可是只能扩展一个父类;
  4. 接口能够用于支持回调,而继承并不具有这个特色;
  5. 抽象类不能被密封;
  6. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,固然您也能够声明为虚的;
  7. (接口)与非抽象类相似,抽象类也必须为在该类的基类列表中列出的接口的全部成员提供它本身的实现。可是,容许抽象类将接口方法映射到抽象方法上;
  8. 抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现;
  9. 好的接口定义应该是具备专注功能性的,而不是多功能的,不然形成接口污染。若是一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其余方法,就叫接口污染;
  10. 尽可能避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。由于继承的层次增多,形成最直接的后果就是当你调用这个类群中某一类,就必须把他们所有加载到栈中!后果可想而知。(结合堆栈原理理解)。同时,有心的朋友能够留意到微软在构建一个类时,不少时候用到了对象组合的方法。好比 asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是很是基本的一个设计原则;

  11. 若是抽象类实现接口,则能够把接口中方法映射到抽象类中做为抽象方法而没必要实现,而在抽象类的子类中实现接口中方法。

②.抽象类和接口的使用

  1. 若是预计要建立组件的多个版本,则建立抽象类。抽象类提供简单的方法来控制组件版本;
  2. 若是建立的功能将在大范围的全异对象间使用,则使用接口。若是要设计小而简练的功能块,则使用接口;
  3. 若是要设计大的功能单元,则使用抽象类。若是要在组件的全部实现间提供通用的已实现功能,则使用抽象类;
  4. 抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

如下是我在网上看到的几个形象比喻。
1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;可是F22属于飞机抽象类,鸽子属于鸟抽象类;
2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我能够给你个具体的铁门或木门(多态);并且只能是门,你不能说它是窗(单继承),一个门能够有锁(接口)也能够有门铃(多实现)。门(抽象类)定义了你是什么,接口(锁)规定了你能作什么(一个接口最好只能作一件事,你不能要求锁也能发出声音吧(接口污染))。

6.mvc和webform

  1. 图解ASP.NET MVC与WebForm的区别
  2. 深刻比较ASP.NET Webform和ASP.NET MVC两种开发方式的优缺点
  3. mvc与三层结构终极区别
  4. MVC:请求过程
  5. asp.net MVC处理机制

7.mvc的filter

  1. [ASP.NET MVC 小牛之路]11 - Filter
  2. ASP.Net MVC开发基础学习笔记:4、校验、AJAX与过滤器点

8.项目中前端用了啥框架,怎么实现,以及如何自定义jquery插件

  1. jquery开发自定义的插件总结
  2. 作自定义轮播

学习闭包:

(1).学习Javascript闭包(Closure)

(2).javascript的闭包

(3).图解闭包

本站公众号
   欢迎关注本站公众号,获取更多信息