????這節來講一下C#中的匿名類型。
匿名類
????在C#中,我們可以不去顯示的聲明一個類,而是通過匿名類去臨時聲明一個類結構去幫助我們去完成一些功能。
????聲明一個匿名類,我們可以像下面這樣做:
var Anonymous=new {name="charles",year=18};//聲明匿名類對象
????需要注意的是,匿名類成員只能聲明公共的只讀屬性,不能在匿名類中聲明方法,因此匿名類的作用主要是承載類的數據,而非類的行為,也就是方法。由匿名類型實例化的對象則被成為匿名對象,匿名對象使用var關鍵字標識。比如說解析一條JSON數據,我們完全可以通過匿名類的形式去獲取我們想得到的數據,請看如下代碼:
string json = " { \"name\":\"charles\" , \"year\":18 ,\"address\":"shandong"}";
var jsonObj = JsonConvert.DeserializeAnonymousType(json, new{name = string.Empty,year = 0});
Console.WriteLine($"name is {jsonObj.name},year is {jsonObj.year}");
????這段代碼使用了Newtonsoft.Json中的一個JSON轉換方法,該方法可以將一條JSON轉換為我們指定的匿名對象。如果沒有匿名對象,我們需要創建一個類,去為了轉換這一JSON,但是使用匿名類就簡單許多,而且實際上我們只需要關注我們需要的屬性即可,至于JSON中的其它對象,我們可以一概丟棄。? ?
????初此以外,我們在使用Linq方法Select()的使用,也可以用匿名類型:
//class AnonymousTemp
//{
// public int Id { get; set; }
// public string Name { get; set; }
// public int Year { get; set; }
//}
List<AnonymousTemp>= new List<AnonymousTemp>();
list.Add(new AnonymousTemp() { Id = 1, Name = "Charles", Year = 18 });
list.Add(new AnonymousTemp() { Id = 2, Name = "Chiron", Year = 18 });
var aList = list.Select(u => new{id = u.Id,name = u.Name});foreach (var item in aList)
{Console.WriteLine($"name is {item.id},year is {item.name}");
}
?????比如我們查到一組集合,我們只關心其中的幾個屬性(當然如果只需要取一個屬性,則不需要匿名類,直接返回該屬性值就可以了),就可以使用匿名類型。上述代碼中 Select方法的參數,接受一個委托,也就引出了匿名方法,但是這個地方我用的并不是匿名方法,而是Lambda表達式,我們接著講。
匿名方法(僅作了解)
????Select方法需要一個委托類型的參數,我們可以直接向里傳入一個方法,傳統的操作需要我們自己聲明一個符合要求的委托,并且為這個委托傳入方法,將這個委托作為參數傳入Select方法中,但是后來為了簡化操作,在C#2.0推出了匿名委托,匿名委托的結構為:
delegate (參數){//方法體}
這樣上述Select方法用匿名方法的形式可以改寫為如下形式:
var aList = list.Select(delegate (AnonymousTemp u)
{return new{id = u.Id,name = u.Name};
});
????這樣看似是簡單了許多,但是為了更加簡單,在C#3.0微軟推出了Lambda表達式,是對于匿名方法的進一步簡化,從對比中我們也可以看出,Lambda表達式寫起來要更爽一些。因此大家對于匿名方法可以僅做了解,而應該著重了解Lambda表達式的使用。
真的匿名?
????匿名方法真的匿名嗎?為此,我們可以反編譯一下這個項目,就能看到,無論是匿名類還是匿名方法,編譯器在編譯時都會為我們創建一個類,雖然我們寫的少的,但編譯器并沒有少做:
????下圖是編譯器解析匿名類,為我們生成的真正的類代碼:
????下圖是編譯器解析匿名方法和Lambda表達式,為我們生成的一個類,這個類里邊是兩個方法,分別對應我寫的匿名方法和Lambda表達式,我們可以看出它們最終都被編譯為一個委托:
????但盡管如此,匿名類或者匿名方法也只能在其所在的上下文中使用,并不能跨作用域訪問。
本節到此結束...