Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

В этом выпуске - окончание перевода статьи "Сравнительный обзор C#", обзор новостей,


Информационный Канал Subscribe.Ru

.Net Собеседник #5

Содержание
  1. От автора
  2. Обзор новостей
  3. C# vs Java vs C++ 
  4. Время кода - Синхронизация значения identity между таблицей БД и таблицей в наборе данных
  5. Форумы .Net на www.sql.ru

От автора

Здравствуйте, коллеги!

Сейчас я разрабатываю веб-приложение, которое, взаимодействуя с MS SQL сервером, получает от него набор данных по запросу SELECT и отображает этот набор в компоненте DatGrid. По ходу разработки выяснилось, что неплохо было бы пронумеровать строки в DataGrid’e. В принципе такую задачу можно выполнить и средствами SQL сервера, т.е. вернуть уже пронумерованный набор, но мне, естественно, стало интересно решить эту задачу на стороне клиента. В результате небольшого исследования родилось два способа нумерации строк в компоненте DataGrid.

В упрощенном виде таблица выглядит так:

CREATE TABLE [dbo].[tblFIO] (
[id] [bigint] IDENTITY (1, 1) NOT NULL ,
[fio] [nvarchar] (50) COLLATE Cyrillic_General_CI_AS NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblFIO]
ADD CONSTRAINT [PK_tblFIO] PRIMARY KEY CLUSTERED ( [id] )
ON [PRIMARY]
GO

Способ первый, который пришёл мне на ум, заключается в том, что можно заменить значения столбца id, значения которого мне не были нужны для отображения, значениями порядкового номера. Как это можно сделать? Да очень просто – выполнив запрос “SELECT * FROM tblFIO” мы как обычно заполняем экземпляр класса DataSet, подсоединяем его к нашему DataGrid’у, а в обработчике события DataGrid1_ItemDataBound пишем следующий код:


if (e.Item.ItemType==ListItemType.AlternatingItem || e.Item.ItemType==ListItemType.Item){
e.Item.Cells[0].Text = (++increment).ToString();
}

В этом коде происходит замена значений поля id таблицы tblFIO на значение приватного целочисленного поля класса нашей веб-страницы increment, значение которого увеличивается с каждой новой строкой, выводимой в наш экземпляр класса DataGrid.
В общем-то этот пример хоть и рабочий, но он является типичным примером решения задачи «в лоб», поэтому не красив, хотя определённая доля хитрости тут присутствует.
Второй способ гораздо «правильнее» и наверняка эффективнее.
Начнём с того, что запустим Property Builder для нашего DataGrid’a и выберем закладку Columns, в ней есть возможность добавить Template Column в наш DataGrid, что мы и сделаем. В HTML-коде это будет выглядеть так:

<form id="Form2" method="post" runat="server">
<asp:DataGrid id="DataGrid1" runat="server" Width="100%" DataSource="<%# ds1 %>" DataMember="tblFIO">
<Columns>
<asp:TemplateColumn HeaderText="№ п/п">
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form>

Теперь к классу страницы добавим свойство, которое будет возвращать всё тоже значение поля increment:

public string GetIncrement {
get {
return (++increment).ToString();}
}

А в тег asp:TemplateColumn добавим метку, которая будет отображать значения свойства GetIncrement:

<Columns>
<asp:TemplateColumn HeaderText="№ п/п">
<asp:ItemTemplate>
<asp:Label runat="server" Text='<%# GetIncrement %>'/>
</asp:ItemTemplate>
</asp:TemplateColumn>
</Columns>

Вот собственно и всё – результат один и тот же, но подходы совершенно различны. Заодно мы с вами познакомились и с шаблонами, с помощью которых можно легко настроить DataGrid (да и не только) на свой вкус, о чём мы может быть и поговорим в одном из следующих выпусков.

На этом всё, желаю интересного чтения.

{К содержанию}

Обзор новостей

  1. Вышел Microsoft SQL Server 2000 Reporting Services

    Редмонд, Вашингтон. – Корпорация Microsoft 27.01.2004 г. объявила о выходе SQL Server (TM) 2000 Reporting Services. Reporting Services предлагает потребителям мощный инструмент для создания отчётов, который поможет увеличить степень контроля над вашим бизнесом путём предоставления информации в реальном времени из любого источника данных на любое устройство. В результате сотрудники всех уровней получат лучший доступ к информации, что даст им возможность принимать решения на основе большего её количества и быть более ценными работниками в компании. С появлением Reporting Services, SQL Server, как часть Microsoft® Windows Server System (TM) , становится единой всеобъемлющей платформой для управления данными и сбора сведений о бизнесе, с интегрированной аналитикой, включающей OLAP (online analytical processing); добычу и хранение данных; инструменты для экстракции, трансформирования и загрузки данных; отчётной функциональностью. Это интегрированное комплексное решение поможет компаниям принимать лучшие решения за короткий промежуток времени при низкой стоимости владения этим продуктом.
    "Reporting Services является на сегодняшний день лучшим решением для создания отчётов уровня корпорации на рынке подобных решений. Будучи построен для безусловно успешного продукта SQL Server 2000, он предлагает интегрированное и масштабируемое решение в независимости от того, скольким пользователям необходимо предоставить отчёт – 5 или 50,000", - говорит Пол Флесснер (Paul Flessner), первый вице-президент, курирующий отделение корпоративных серверов в Microsoft. "С Reporting Services, наши клиенты пользуются преимуществом решения для создания отчётов, характеризующегося как недорогое, лёгкое в использовании решение, которое поможет гораздо проще использовать накопленные данные для принятия изящных и эффективных бизнес-решений."

    Для работы Reporting Services необходима лицензия для каждого SQL Server 2000, на котором он установлен. Продукт доступен на девяти языках – включая традиционный и упрощённый китайский, английский, французский, немецкий, итальянский, японский, корейский и испанский.

  2. Открылся сайт поддержки рассылки .Net Собеседник
    Благодаря любезному предложению создателя сайта http://www.sql.ru/  Александра Сибилева, выделившего место для сайта поддержки рассылки .Net Собеседник, вы можете получить доступ к архиву рассылки по ссылке http://www.sql.ru/users/hdrummer.

    В дальнейшем планируется на сайте выкладывать исходные тексты проектов, которые были использованы как источник информации для рассылки.

  3. Вышел Mono Scheduler ASP.NET
    Mono Software объявила о выходе Mono Scheduler, мощного и простого в использовании ASP.NET компонента, позволяющего разработчикам добавлять в свои приложения функциональность календаря и планировщика.
    Дата выхода : 22 января 2004 г.

  4. Большое обновление библиотеки CodeBox для .NET
    В библиотеку CodeBox для .NET были добавлены более чем 100 новых процедур как для VB.NET, так и для C# версии, теперь она содержит более 300 уникальных процедур! Не упустите возможность приобрести это уникальное хранилище кода и браузер к нему.
    Дата выхода : 20 января 2004 г.

  5. Опубликована "дорожная карта" для Mono
    Novell, владелец компании Ximian, 25 января 2004 г. раскрыло «дорожную карту» для Mono - реализацию платформы .NET с открытым кодом. В частности, Mono 1.0 ожидается к поставке во втором квартале 2004 г., а будущие релизы будут включать поддержку особенностей .NET 1.2 (Whidbey).

    В список поддерживаемых особенностей включены "профили библиотек" для версий .NET 1.0, 1.1, и ECMA-стандартизированные профили, а также JIT (Just-in-Time) и AOT (Ahead-of-Time) компиляция во внутренний код для архитектур x86 и PowerPС. (Другие архитектуры будут поддерживаться через интерпретаторы)

  6. Вышел eStream PanelBar v1.2
    eStream PanelBar.NET позволяет разработчикам создавать привлекательные меню для веб-сайтов и веб-приложений буквально двумя строчками кода.
    Дата выхода: 25.01.2004 г.

  7. Вышел HarnessIt v1.4.0.2 (.NET Unit Testing)
    Доступна для скачивания новая версия продукта HarnessIt. Этот выпуск нашего ПО для тестирования программных модулей был наделен более высокой совместимостью для работы сразу с двумя платформами .NET - 1.0 и 1.1. Посетите наш сайт – продукт можно скачать бесплатно.
    Дата выхода: 23.01.2004 г.

  8. Выпущен StudioSpell v1.0, проверка правописания для Visual Studio .NET
    StudioSpell – лёгкая в использовании надстройка для Microsoft Visual Studio .NET (2002 и 2003), являющаяся инстурментом для проверки строк в HTML-страницах и в исходном коде. StudioSpell проверяет только тот текст, который будет виден пользователю.
    Дата выхода: 23.01.2004 г.

  9. Анонсирована Professional Validation And More ("VAM") v2.0
    ПО второго поколения VAM преодолевает ограничения валидаторов Microsoft и существенно расширяет набор инструментов и саму концепцию проверки ввода на соответствие. 22 валидатора оснащены новыми возможностями для привлечения внимания пользователя к ошибкам ввода. VAM также включает клиентский набор инструментов, набор элементов управления и инструментов, которые помогут вам создать более интерактивную веб-форму без написания кода на JavaScript, поддерживающего все существующие браузеры. Цена на VAM - от $50 (US).
    Дата выхода: 21.01.2004 г.

{К содержанию}

C# vs Java vs C++ :: окончание, начало см. в №3

Сравнительный обзор C#

ЯЗЫК: C#
Автор: Ben Albahari
Компания: Genamics
Дата: 31.07.2000, обновлено 10 Августа 2000.
Благодарности, в алфавитном порядке: Don Box, C.R. Manning, Joe Nalewabau, John Osborn, Thomas Rhode и Daryl Richter за их отзывы и поддержку

ПЕРЕВОД: Чужа В.Ф. ака hDrummer


Содержание

  1. C# и Java
  2. Свойства
  3. Индексаторы
  4. Делегаты
  5. События
  6. Перечисления
  7. Коллекции и Foreach
  8. Структуры
  9. Унификация типов
  10. Перегрузка операторов
  11. Полиморфизм
  12. Интерфейсы
  13. Версионность
  14. Модификаторы параметров
  15. Атрибуты
  16. Конструкции выбора
  17. Предопределённые типы
  18. Модфикаторы полей
  19. Конструкции перехода
  20. Сборки, пространства имён, уровни доступа
  21. Действия с указателями
  22. Прямоугольные массивы
  23. Конструкторы и деструкторы
  24. Управляемая среда выполнения
  25. Библиотеки
  26. Интероперабельность
  27. Выводы

11. Арифметические действия с указателями

На языке C# арифметические действия с указателями могут быть выполнены в методах, помеченных модификатором unsafe. В том случае, когда указатель указывает на объекты, за которые отвечает сборщик мусора, компилятор использует принудительно фиксированный адрес для указания на объект. Это делается из-за того, что сборщик мусора регулярно чистит память и перемещает объекты в ней. А в том случае, если вы имеете дело с указателями и произойдёт очистка или перемещение объекта, указатель будет указывать на какой-то мусор. Выбор термина "unsafe" вполне оправдан – я надеюсь, что это предостережет разработчика от использования указателей, разве что кроме тех случаев, когда они действительно нужны.

22. Прямоугольные массивы

В C# поддерживаются как прямоугольные, так и «рваные» массивы. «Рваные» массивы являются аналогами массивов в Java. Прямоугольные массивы более эффективны и аккуратны в решении некоторых проблем. Примером такого массива может быть:

int [,,] array = new int [3, 4, 5]; // создаёт 1 массив
int [1,1,1] = 5;

Использование «рваных» массивов:

int [][][] array = new int [3][4][5]; // создаёт 1+3+12=16 массивов
int [1][1][1] = 5;

В совокупности со структурами (struct), C# может предложить высокий уровень быстродействия операций, необходимых для работы в таких областях, как графика и математика.

23. Конструкторы и деструкторы

Вы можете указать опциональные параметры конструктора:

class Test
{
public Test () : this (0, null) {}
public Test (int x, object o) {
}
}

          Можно создать статический конструктор:

class Test
{
static int[] ascendingArray = new int [100];
static Test () {
for (int i = 0; i < ascendingArray.Length; i++)
ascendingArray [i] = i;
}
}

По соглашению о наименованиях в C++, деструктор в этом языке обозначается символом ~. Деструкторы могут быть созданы только для ссылочных типов и не могут быть перегружены. Деструктор не может быть вызван явно, поскольку это не имеет смысла в том случае, когда жизненным циклом объекта управляет сборщик мусора. Деструктор каждого объекта в иерархии объектов (от самых дальних потомков до самого первого предка или корневого объекта) вызываются перед тем, как освобождается память, занимаемая этим объектом.

Несмотря на подобие деструкторов в C# и C++, деструкторы в C# больше похожи на Java finalizer’ы . Причина этого – в том, что они также вызываются сборщиком мусора, а не вызываются самим программистом. Более того, как и finalizer’ы Java, они не могут гарантировать вызова во всех случаях (обычно это шокирует любого, кто впервые слышит об этом). Если вы программируете таким образом, что знаете когда будет вызван деструктор объекта (т.н. детерминистское программирование), тогда вам стоит присмотреться к другой модели при переходе на Java или C#. Модель, которую Microsoft рекомендует и которая реализована в .NET – dispose-шаблоны, использование которых состоит в определении метода dispose() для классов, управляющих чужими ресурсами – такими, как соединения с БД. Для распределенного программирования .NET предлагает улучшенную по отношению к DCOM-счётчику ссылок, модель.

24. Управляемая среда выполнения

Попытки сравнения между [C#/IL кодом/CLR] и [Java/байт-кодом/JVM] неизбежны. Я думаю, лучшим способом сравнения в этом случае будет рассмотрение причин возникновения этих технологий.

В случае программ, написанных на C и C++, в общем случае программа компилируется в код, который будет исполняться на определенных типах процессоров и в определённой операционной системе. Компилятору необходимо знать процессор, на котором будет исполняться программа, поскольку процессоры различаются набором поддерживаемых инструкций. Также компилятору необходимо знать целевую ОС, поскольку они различаются тем, каким образом работают исполняемые файлы и как реализованы некоторые основные конструкции C/C++, такие как выделение памяти. Эта модель C/C++ была очень успешной (большинство ПО, которое вы используете, наверняка скомпилировано согласно этим принципам), но у этого подхода есть и свои ограничения:

  • отсутствие интерфейса для взаимодействия с другими программами (технология COM была разработана именно по этой причине)
  • не позволяет распространять программу в виде, приемлемом для других платформ
  • не позволяет организовать исполнение программы по принципу «песочницы» для соблюдения соображений безопасности

В Java эти проблемы решаются также, как это делалось в Smalltalk – компилирование в байт-код, который исполняется в виртуальной машине. Байт-код содержит основную структуру программы, что предоставляет возможность для взаимодействия между программами. Байт-код также машинно-независим, что означает возможность использования одного и того же файла класса на разных платформах. И наконец, поскольку язык Java не обладает средствами прямого управления памятью (через указатели), это делает его пригодным для написания программ, исполняемых в «песочнице».

Изначально виртуальные машины имели интерпретатор, на лету конвертировавший поток инструкций байт-кода в код машинный, но этот ужасающе медленный процесс всегда отталкивал программистов, требовательных к скорости исполнения программ. Сегодня большинство виртуальных машин Java используют JIT (Just-In-Time) компилятор, который попросту компилирует классы в машинный код перед тем, как они попадают в область видимости и тела методов перед их выполнением. Существует также возможность перед запуском целиком скомпилировать программу на Java в машинный код для того, чтобы исключить время ожидания при запуске и сэкономить память на JIT-компиляторе. Однако, в отличие от скомпилированной программы написанной на Visual C++, этот процесс не означает полной независимости программы от библиотеки времени выполнения. Среда исполнения программ на Java (также называемая "Java Virtual Machine" или виртуальной машиной Java, JVM) обеспечивает функционирование многих жизненно важных частей программы, таких как сборка мусора и обеспечение безопасности. Эта среда также называется «управляемой средой исполнения».

И хотя в .Net используется немного другая терминология, в целом модель .NET выглядит также, как описано выше, хотя она разрабатывалась с целью избежать использования интерпретации. Многие преимущества платформы .NET связаны с собственно дизайном IL, в то время как единственной возможностью заполучить эти особенности для языка Java заключаются в изменении спецификации байт-кода, что неизбежно приведёт к серьёзным проблемам совместимости. Я не хотел бы здесь останавливаться детально на этих особенностях – оставим их для той небольшой группы разработчиков, которые разбираются и в байт-коде и в IL-коде. Для 99% разработчиков, таких как я, которые не собираются рыться в дебрях спецификации IL-кода, я приведу лишь некоторые дизайнерские решения для IL, имеющие преимущество перед байт-кодом:

  • лучшая поддержка нейтральности типов (для реализации шаблонов)
  • лучшая поддержка нейтральности к языкам
  • всегда компилируется перед выполнением и никогда не интерпретируется
  • позволяет добавлять к классам, методам и т.д. дополнительную информацию (см. Гл.15 Атрибуты)
На данный момент в CLR ещё не реализована поддержка разных ОС, но она предлагает более высокую интероперабельность, чем JVM в других областях. (См. Гл.26 Интероперабельность)

25. Библиотеки

        Любой язык практически бесполезен без библиотек. В C# достаточно немного базовых библиотек, но этот недостаток восполняется использованием библиотек платформы .NET (некоторые из них написаны на C#). Но так как эта статья посвящена в основном языку C#, а не платформе .NET, то мы не будем останавливаться на этих библиотеках – они достойны отдельной статьи. Коротко, библиотеки .NET включают поддержку Threading, Collection, XML, ADO+, ASP+, GDI+ и WinForms. Некоторые из них кросс-платформенны, другие завязаны на Windows, а вот о кросс-платформенности мы и поговорим в следующей главе.

26. Интероперабельность или взаимодействие

         
Думается, было бы полезно разбить возможность взаимодействия на три группы: межъязыковое взаимодействие, межплатформенное взаимодействие и взаимодействие между стандартами. В то время как сила Java в межплатформенном взаимодействии, сила C# заключается в межъязыковом взаимодействии. Оба языка имеют как сильные, так и слабые стороны во взаимодействии между стандартами.

Межъязыковое взаимодействие

          Межъязыковое взаимодействие обеспечивается уровнем и лёгкостью интеграции с другими языками. Как виртуальная машина Java, так и CLR(Common Language Runtime) позволяют вам писать программы на многих языках, поскольку в итоге они компилируют в байт-код или IL-код соответственно. Однако, платформа .NET позволяет сделать намного больше, чем просто скомпилировать программу, написанную на другом языке в IL-код. NET в высокой степени позволяет множеству разных языков свободно использовать и расширять библиотеки друг друга. Например, программист, использующий Eiffel или Visual Basic может импортировать класс C#, перегрузить виртуальный метод этого класса и теперь объект, написанный на C# будет использовать метод, написанный на Visual Basic (пример полиморфизма). Если вы удивлены таким примером, добавлю, что VB.NET был существенно модернизирован (за счёт совместимости с VB6) и теперь поддерживает все современные возможности ООП.

Языки, поддерживающие .NET, обычно легко интегрируются в среду Visual Studio.NET и, при необходимости, используют те же самые RAD-особенности, что и «родные» языки этой платформы.

C# также поддерживает P/Invoke, использование которого намного проще (отсутствие dll) при взаимодействии с C-кодом, чем использование JNI в Java. Эта особенность очень похожа на J/Direct, которую мы знаем по Microsoft Visual J++.

           Межплатформенное взаимодействие

Этот термин всегда обозначал интероперабельность операционных систем, однако в последние несколько лет интернет-браузеры сами стали рассматриваться как платформы.

C#-код исполняется в управляемой среде, это и есть самый важный технологический момент для исполнения C#-кода в разных операционных системах. Однако, некоторые библиотеки .NET привязаны к Windows, например, библиотеки WinForms, которые, в свою очередь, завязаны на Windows API. Есть проект портирования Windows API на Unix-системы, но это только проект, в то время как сама Microsoft не предпринимает в этом направлении никаких усилий.

Однако это не значит, что в Microsoft игнорируют межплатформенное взаимодействие. Библиотеки .NET предлагают широкие возможности для написания решений с использованием HTML/DHTML. Для решений, которые могут быть реализованы с помощью HTML/DHTML клиента, C#/.NET – это очень хороший выбор. Для кроссплатформенных проектов с более высокими требованиями к интерфейсу клиента, Java будет тоже хорошим выбором. Kylix, версия Delphi, позволяющая компилировать один и тот же код для Windows и Linux, тоже может быть вполне удовлетворительным выбором (Если Borland всё же будет его развивать дальше. - Прим. переводчика.)

Microsoft стандартизировала как C#, так и составные компоненты .NET в ECMA.

          Взаимодействие между стандартами

Всё, что можно использовать в языке, так или иначе имеет свои стандарты, будь то СУБД, графические библиотеки, протоколы интернет или межъобъектных коммуникаций (COM и CORBA). Поскольку компания Microsoft является обладателем многих стандартов и играет большую роль в их разработке, то ей достаточно легко их поддерживать. Конечно, у них есть бизнес-мотивации (я не говорю, что это их оправдывает или не оправдывает) оказывать меньшую поддержку стандартам, которые являются соперниками их собственных, например CORBA соперничает с COM, а OpenGL с DirectX. Также и бизнес-мотивации Sun (я снова повторю, что не говорю, что это их оправдывает или не оправдывает) приводят к тому, что Java не так хорошо поддерживает стандарты Microsoft, как могла бы.

Объекты C#, поскольку они реализованы как объекты .NET, могут быть автоматически использованы как COM-объекты. В тоже время, C# умеет как использовать, так и предоставлять для использования COM-объекты, что позволит использовать в проектах на C# огромную базу уже написанного COM-кода. .NET – это та технология, которая постепенно заменит COM, я уверен, что и .Net в своё время уступит место следующей волне технологий. Однако этой платформе суждена долгая и интересная жизнь!

27. Выводы

Надеюсь, эта статья дала вам представление того, где находится место C# относительно Java и C++. В целом, я уверен, C# предлагает более богатые выразительные возможности и более приспособлен для написания эффективного кода, чем Java, в тоже время обладая элегантностью Java и простотой, оба языка выглядят более привлекательными, чем C++.

Ben Albahari ,
Genamics.

{К содержанию}

Время кода

Синхронизация значения identity между таблицей БД и таблицей в наборе данных

ЯЗЫК: C#
ВЕРСИИ ASP.NET: 1.0 | 1.1
АВТОР: Bipin Joshi,
http://www.dotnetbips.com/
ПЕРЕВОД: Чужа В.Ф ака hDrummer

Проблема
Представьте себе, что вы получили набор записей из таблицы Employee (база данных Northwind на SQL Server’e) в DataSet для того, чтобы провести обновление данных. В таблице Employee есть поле EmployeeID, которое является identity-полем. Теперь добавим несолько новых записей в DataTable с помощью нашего приложения, после чего нужно записать данные обратно в таблицу БД. Обычно вы используете свойство InsertCommand объекта класса DataAdapter для того, чтобы занести изменения в таблицу БД. Однако в данном случае есть небольшая проблема – после вставки записей в таблицу БД, наш DataTable автоматически не получит те значения поля EmployeeID, которые были присвоены в БД. Поэтому мы будем вынуждены снова заполнить DataSet для того, чтобы получить их и использовать для работы. В итоге получаем два запроса к БД – один для вставки записей, а второй – для перезаполнения набора данных новыми значениями поля identity. Не лучший подход в случае частого обновления данных и большого количества пользователей, не так ли?

Решение
Вышеприведенная проблема может быть решена искусным использованием хранимых процедур и выходных параметров. Вместо использования оператора INSERT для обновления таблицы БД, мы создадим ХП InsertRow, код которой приведен ниже:

CREATE PROCEDURE dbo.InsertRow
(
@fname varchar(50),
@lname varchar(50),
@empid int output
)
AS
Insert into employees(firstname,lastname) values(@fname,@lname);
set @empid=@@identity;
RETURN

Здесь мы видим выходной параметр @empid, который устанавливается в значение @@identity после выполнения вставки. Поскольку этот параметр выходной, то после вызова метода Update объекта класса DataAdapter, он автоматически заполняет поле EmployeeID нашего объекта класса DataTable. Таким образом мы за одно обращение к БД выполним вставку записи и синхронизируем таблицу в нашем наборе данных новым значением поля identity.

{К содержанию}

Форумы .Net - вопросы оставшиеся без ответа

универсальное средство для создания БД
ADODB >> Excel
Навигатор
FireBird .Net Provider 1.0/1.1
<OPTION value="????? ???">????? ???</OPTION>
ASP.NET Design Patterns - где можно почитать?
нужна помощь
CommandBuilder

На этом пятый выпуск .Net Собеседника закончен.
До следующего номера.


Чужа Виталий Ф. aka hDrummer,
hdrummer@sql.ru - жду ваши предложения, вопросы и замечания.


Рассылки Subscribe.Ru
.Net Собеседник - Новости мира Net, C#, ASP.Net


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное