Упрощённая инициализация объектов




Зачастую бывает нужно инициализировать тип с некоторыми заранее заданными значениями свойств, отличными от значений по умолчанию. Допустим, у нас есть класс Forum:

Код C# 3.0

public class Forum {

string _name;

string _admin;

string _url;

int _membersCount;

 

public string Name {

get { return _name; } set { _name = value; }

}

 

public string Admin {

get { return _admin; } set { _admin = value; }

}

 

public string URL {

get { return _url; } set { _url = value; }

}

 

public int MembersCount {

get { return _membersCount; } set { _membersCount = value; }

}

}

 

Код VB.NET 9.0

Public Class Forum

Private _name As String

Private _admin As String

Private _url As String

Private _membersCount As Integer

 

Public Property Name() As String

Get

Return _name

End Get

Set(ByVal value As String)

_name = value

End Set

End Property

 

Public Property Admin() As String

Get

Return _admin

End Get

Set(ByVal value As String)

_admin = value

End Set

End Property

 

Public Property URL() As String

Get

Return _url

End Get

Set(ByVal value As String)

_url = value

End Set

End Property

 

Public Property MembersCount() As Integer

Get

Return _membersCount

End Get

Set(ByVal value As Integer)

_membersCount = value

End Set

End Property

End Class

Для того, чтобы объявить форум Vingrad, нам пришлось бы писать вот такое:

Код C# 3.0

Forum vingrad = new Forum();

vingrad.Admin = "WoWa";

vingrad.MembersCount = 17000;

vingrad.Name = "Vingrad";

vingrad.URL = " https://forum.vingrad.ru ";

 

Код VB.NET 9.0

Dim vingrad As New Forum

vingrad.Admin = "WoWa"

vingrad.MembersCount = 17000

vingrad.Name = "Vingrad"

vingrad.URL = " https://forum.vingrad.ru "

К счастью, в C# 3.0 появилась такая вот конструкция:

Код C# 3.0

Forum vingrad = new Forum(){Admin = "WoWa",

MembersCount = 17000,

Name = "Vingrad",

URL = " https://forum.vingrad.ru "};

Код VB.NET 9.0

Dim vingrad As New Forum {Admin:= "WoWa", _

MembersCount:= 17000, _

Name:= "Vingrad", _

URL:= " https://forum.vingrad.ru "}

Честно говоря, мне не очень понравился синтаксис VB.NET с:=, уж больно это напоминает Паскаль...:)

Эта конструкция существенно упрощает составление запросов. Скажем, мы можем написать

Код C# 3.0

IEnumerable<Forum> makeMeSuperAdmin = forums.Select(

forum => new Forum {

Admin = "Exception",

MembersCount = forum.MembersCount,

Name = forum.Name,

URL = forum.URL});

и даже

Код C# 3.0

string[] forumNames = {"Vingrad", "RSDN", "GotDotNet"};

IEnumerable<Forum> myOwnForums = forumNames.Select(

forumName => new Forum {

Admin = "Exception",

MembersCount = 1000000,

Name = forumName,

URL = "https://" + forumName + ".ru"});

Ну а если писать, используя стандартную запись для операторов запросов, выйдет вот что:

 

Код C# 3.0

string[] forumNames = { "Vingrad", "RSDN", "GotDotNet"};

IEnumerable<Forum> myOwnForums = from forumName in forumNames

select new Forum {

Admin = "Exception",

MembersCount = 1000000,

Name = forumName,

URL = "https://" + forumName + ".ru"};

Код VB.NET 9.0

Dim forumNames() As String = {"Vingrad", "RSDN", "GotDotNet"}

Dim myOwnForums As IEnumerable(Of Forum) = _

Select New Forum { _

Admin:= "Exception", _

MembersCount:= 1000000, _

Name:= forumName, _

URL:= "https://" + forumName + ".ru"} _

From forumName In forumNames

Таким образом, мы получаем из массива string перечисление IEnumerable<Forum>.

Анонимные типы

У Вас бывали ситуации, что нужно объявить класс только для одноразового использования? Нет? Значит, будут:) Допустим, перед нами стоит задача вывести на консоль только данные о названии и количестве участников форума. Представим, что Forum – довольно большой класс, и использование его при выводе на консоль всего нескольких свойств может понизить производительность из-за большого расхода памяти. Какие у нас есть выходы?

1) Без LINQ и анонимных типов

Рациональные методы отсутствуют (то есть без расхода памяти и с понятным кодом)

2) С LINQ, без анонимных типов

Создать структуру ForumStatistics со свойствами ForumName и MembersCount. Затем делать выборку вот таким запросом:

Код C# 3.0

IEnumerable<Forum> forums = //...

IEnumerable<ForumStatistics> forumStats = from forum in forums

select new ForumStatistics {

MembersCount = forum.MembersCount,

Name = forum.Name};

Код VB.NET 9.0

Dim forums As IEnumerable(Of Forum) = '...

Dim forumStats As IEnumerable(Of ForumStatistics) = _

Select New ForumStatistics { _

MembersCount:= forum.MembersCount, _

Name:= forum.Name} _

From forum In forums

 

3) C LINQ и анонимными типами

Здесь всё ещё проще. Нам даже не нужно создавать структуру ForumStatistics. Компилятор создаcт её автоматически, что сохранит нам время, а следовательно, деньги:)

Сейчас позволю себе небольшое лирическое отступление, т.к. не всё может быть понятно.

В C# 3.0 и VB.NET 9.0 можно писать код без объявления типов: компилятор сам поймёт, какой тип использовать. Например, код

Код C# 3.0

string s = "Bob";

int n = 32;

bool b = true;

Код VB.NET 9.0

Dim s As String = "Bob"

Dim n As Integer = 32

Dim b As Boolean = True

можно переписать, как

Код C# 3.0

var s = "Bob";

var n = 32;

var b = true;

Код VB.NET 9.0

Dim s = "Bob";

Dim n = 32

Dim b = True

, не теряя функциональности и производительности. С таким кодом даже работает IntelliSense! Правда, на такие объявления есть несколько ограничений:

i) Выражение всегда должно инициализироваться!

ii) Таким образом нельзя объявлять перечислимые типы

iii) Нельзя инициализировать выражение null’ем

Зачем же нужен этот «изврат», если можно так выразиться? Ответ прост: он позволяет не морочить себе голову при объявлении некоторых сложных типов и он также позволяет объявлять анонимные типы. Давайте рассмотрим наш пример. Код из пункта 2 можно переписать так:

Код C# 3.0

IEnumerable<Forum> forums = //...

var forumStats = from forum in forums

select new {

MembersCount = forum.MembersCount,

Name = forum.Name};

 

 

Код VB.NET 9.0

Dim forums As IEnumerable(Of Forum) = '...

Dim forumStats = _

Select New { _

MembersCount:= forum.MembersCount, _

Name:= forum.Name} _

From forum In forums

Самое приятное, что для анонимных типов по-прежнему доступен IntelliSense:

Впрочем, о поддержке IntelliSense, да и LINQ в VS 2005 мы поговорим позднее.

Если посмотреть Reflector’ом в сгенерированную сборку, видно, что компилятор сгенерировал анонимный тип _Anonymous_Main_7_1C. Кстати, использование анонимных типов имеет и обратную сторону: новички могут использовать их где попало, что, разумеется, затруднит чтение и понимание кода. Например, станет возможным творить вот такие «извраты»:

Код C# 3.0

var bob = new { Name = "Bob", Age = 51, CanCode = true };

var jane = new { Age = 29, FirstName = "Jane" };

 

var couple = new {

Husband = new { bob.Name, bob.Age },

Wife = new { Name = jane.FirstName, jane.Age }

};

 

int ha = couple.Husband.Age; // ha == 51

string wn = couple.Wife.Name; // wn == "Jane"

Код VB.NET 9.0

Dim bob = New {Name:= "Bob", Age:= 51, CanCode:= True}

Dim jane = New {Age:= 29, FirstName:= "Jane"}

Dim couple = New { _

Husband:= New {bob.Name, bob.Age}, _

Wife:= New {Name:= jane.FirstName, jane.Age} _

}

Dim ha As Integer = couple.Husband.Age ' ha = 51

Dim wn As String = couple.Wife.Name ' wn = "Jane"

Кстати, свойства Husband и Wife получают имена Name и Age от соответствующих свойств bob и jane, им переданных. Можно написать и более подробно:

Код C# 3.0

var couple = new {

Husband = new { Name = bob.Name, Age = bob.Age },

Wife = new { Name = jane.FirstName, Age = jane.Age }

};

Код VB.NET 9.0

Dim couple = New { _

Husband:= New { Name:= bob.Name, Age:= bob.Age }, _

Wife:= new { Name:= jane.FirstName, Age:= jane.Age } _

}



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-06-26 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: