.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).圖解閉包

本站公眾號
   歡迎關注本站公眾號,獲取更多信息