Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

ЧаВо - Частые Вопросы

273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
Здесь выкладываем свои мысли по поводу решения актуальных задач.
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
Иногда бывает нужно определить, как несимвольная клавиша нажата:
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System;[/FONT][/SIZE][SIZE=2]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Text;[/FONT][/SIZE]
[SIZE=2]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]namespace[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Sample[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Program
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] {[/FONT][/SIZE][SIZE=2]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]   static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] args)[/FONT]
[FONT=Courier New]   {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]     ConsoleKeyInfo[/COLOR][/SIZE][SIZE=2] keyInfo = [/SIZE][SIZE=2][COLOR=#008080]Console[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].ReadKey();[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]     string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] keyName = keyInfo.Key.ToString();[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]     Console[/COLOR][/SIZE][SIZE=2].WriteLine([/SIZE][SIZE=2][COLOR=#800000]"Pressed key name: {0}"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New], keyName);[/FONT][/SIZE][SIZE=2]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New] }[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
.NET Framework 2.x предоставляет средства для архивации/распаковки данных. Предлагается два механизма: GZIP и DEFLATE. Сэмпл смотрим в аттаче
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
Думаю, объяснять что такое Component Object Model (COM) и механизмы работы не надо. Покажу, как создать COM+ компонент средствами .NET Framework. Для необходимо создать интерфейс, который мы хотим опубликовать. Класс который его реализует, потом GUID для класса и интерфейса (GLobal Unique IDentifier), AppID и ещё кое-какие настройки. Подключаем System.EnterpriseServices. Объявляем в файле AssemblyInfo.cs такой атрибут:
 
Код:
[SIZE=2][FONT=Courier New][assembly: [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]ApplicationActivation[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]ActivationOption[/COLOR][/SIZE][SIZE=2].Server)]
[/SIZE][/FONT]

Который говорит о том, что наша библиотека является COM-сервером компонента.
Далее задаём GUID для сборки (GUID создаём утилитой, входящей в состав MSVS):
 
Код:
[SIZE=2][FONT=Courier New][assembly: [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Guid[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"040c8dc5-d6c7-4f52-84ed-210d2bbc6b5f"[/COLOR][/SIZE][SIZE=2])]
[/SIZE][/FONT]

Задаём AppID:
 
Код:
[SIZE=2][FONT=Courier New][assembly: [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]ApplicationID[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"040c8dc5-d6c7-4f52-84ed-210d2bbc6b5f"[/COLOR][/SIZE][SIZE=2])]
[/SIZE][/FONT]

AppID можно задать таким же как и GUID сборки.
Далее даём имя нашему приложению:
 
Код:
[SIZE=2][FONT=Courier New][assembly: [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]ApplicationName[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"ComPlusServer"[/COLOR][/SIZE][SIZE=2])]
[/SIZE][/FONT]

Теперь создаём интерфейс и класс для его реализации:
Код:
[FONT=Courier New][SIZE=2][COLOR=#008000]//Если задать ComInterfaceType.InterfaceIsIUnknown, то это означает, что наш интерфейс
[/COLOR][/SIZE][/FONT][SIZE=2][COLOR=#008000][FONT=Courier New]//является производным от интерфейса IUnknown и имеет раннее связывание[/FONT]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//Если задать ComInterfaceType.InterfaceIsIDispatch, то наш интерфейс является[/FONT]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//производным от IDispatch (так называемые disp-интерфейсы) и имеет позднее связывание[/FONT]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//ComInterfaceType.InterfaceIsDual - дуальный интерфейс, обладающий как поздним так[/FONT]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//и ранним связыванием[/FONT]
[/COLOR][/SIZE][SIZE=2][FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]InterfaceType[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]ComInterfaceType[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].InterfaceIsDual)][/FONT]
[FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Guid[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"A707BF29-D091-4b11-AFA3-7917F44F187E"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]interface [/COLOR][/SIZE][SIZE=2][COLOR=#008080]IMyComPlusInterface
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] MyComPlusMethod();[/FONT]
[FONT=Courier New]}[/FONT]
 
[FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]ClassInterface[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]ClassInterfaceType[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].None)][/FONT]
[FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Guid[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"62B4C28E-F345-4cc1-8D85-63A98DE5240B"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]MyComPlusClass[/COLOR][/SIZE][SIZE=2] : [/SIZE][SIZE=2][COLOR=#008080]ServicedComponent[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#008080]IMyComPlusInterface[/COLOR][/SIZE][SIZE=2][COLOR=#008000]//ServicedComponent должен наследоваться всеми классами, реализующими COM интерфейсы
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]{[/FONT]
[FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]AutoComplete[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][SIZE=2])] [/SIZE][SIZE=2][COLOR=#008000]//используется в схеме транзакций COM+
[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] MyComPlusMethod()[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] int[/COLOR][/SIZE][SIZE=2] a = 5, b = 4, c = a + ~b + 1; [/SIZE][SIZE=2][COLOR=#008000]//реализуем метод
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]}[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]
[SIZE=2]
Осталось зарегистрировать нашу библиотеку:
 
Код:
gacutil /i file-name.dll
regsvcs /tlb: file-name.tlb file-name.dll

И несколько рекомендации по типам аргументов и возвращаемых значений в методах COM-интерфейсов. Использование следующих типов не введёт приложения, работающие с вашим COM-интерфейсом через OLE Automation в ступор:
short, int, string, single, double, currency, DateTime, bool, byte, OleVariant. Так можно использовать маршаллинг с помощью аттрибута MarshalAsAttribute
[/SIZE]
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
Существует несколько способов получения имён SQL-серверов.
Самый простой - реестр Windows (но работает только для локальных серверов):
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Collections.Generic;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Microsoft.Win32;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]namespace[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Sample[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Program
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]   static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] args)[/FONT]
[FONT=Courier New]   {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]     string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] servers = [/FONT]
[FONT=Courier New]([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2][])[/SIZE][SIZE=2][COLOR=#008080]Registry[/COLOR][/SIZE][SIZE=2].LocalMachine.OpenSubKey([/SIZE][SIZE=2][COLOR=#800000]"SOFTWARE\\Microsoft\\Microsoft SQL Server"[/COLOR][/SIZE][SIZE=2]).GetValue([/SIZE][SIZE=2][COLOR=#800000]"InstalledInstances"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]     foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2] sname [/SIZE][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] servers)[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]       Console[/COLOR][/SIZE][SIZE=2].WriteLine([/SIZE][SIZE=2][COLOR=#800000]"{0}\\{1}"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#008080]Environment[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].MachineName, sname);[/FONT]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New] }[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Более простой способ, но работает только в .NET Framework 2.x - через класс System.Data.Sql.SqlDataSourceEnumerator.
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Collections.Generic;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Data;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Data.Sql;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]namespace[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Sample[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Program
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]   static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] args)[/FONT]
[FONT=Courier New]   {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]     DataTable[/COLOR][/SIZE][SIZE=2] servers = [/SIZE][SIZE=2][COLOR=#008080]SqlDataSourceEnumerator[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Instance.GetDataSources();[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]     foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#008080]DataRow[/COLOR][/SIZE][SIZE=2] row [/SIZE][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] servers.Rows)[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]       Console[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].WriteLine(row.ItemArray[0]);[/FONT]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New] }[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Ещё можно узнать через SMO. Добавляем к проекту Microsoft.SqlServer.Smo.dll. Далее:
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Collections.Generic;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Data;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Data.Sql;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]using[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Microsoft.SqlServer.Management.Smo;[/FONT]
[/SIZE][SIZE=2][COLOR=#0000ff][FONT=Courier New]namespace[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Sample[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Program
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]   static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] args)[/FONT]
[FONT=Courier New]   {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]     DataTable[/COLOR][/SIZE][SIZE=2] servers = [/SIZE][SIZE=2][COLOR=#008080]SmoApplication[/COLOR][/SIZE][SIZE=2].EnumAvailableSqlServers([/SIZE][SIZE=2][COLOR=#0000ff]false[/COLOR][/SIZE][SIZE=2]); [/SIZE][SIZE=2][COLOR=#008000]//false говорит о том, что перечисляем не только локальные сервера
[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]     foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#008080]DataRow[/COLOR][/SIZE][SIZE=2] row [/SIZE][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] servers.Rows)[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]       Console[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].WriteLine(row.ItemArray[0]);[/FONT]
[FONT=Courier New]   }[/FONT]
[FONT=Courier New] }[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
[SIZE=2]Поворачиваем надпись при помощи GDI+
Код:
[FONT=Courier New][SIZE=2][COLOR=#0000ff]private [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Form1_Paint([/SIZE][SIZE=2][COLOR=#0000ff]object[/COLOR][/SIZE][SIZE=2] sender, [/SIZE][SIZE=2][COLOR=#008080]PaintEventArgs[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] e)[/SIZE][/FONT][FONT=Courier New][SIZE=2]

{
[/SIZE][LEFT][SIZE=2][COLOR=#008080]Graphics[/COLOR][/SIZE][SIZE=2] gdiObj = e.Graphics; [/SIZE]
[/FONT][LEFT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008000]//получаем GDI+ объект формы[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][/LEFT]

[/COLOR][/SIZE][LEFT][SIZE=2][COLOR=#008080]StringFormat[/COLOR][/SIZE][SIZE=2] strFormat = [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]StringFormat[/COLOR][/SIZE][SIZE=2](); [/SIZE][/LEFT]

[/FONT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008000]//Создаём форматер текста [/COLOR][/SIZE][/FONT]

[FONT=Courier New][SIZE=2]strFormat.FormatFlags = [/SIZE][SIZE=2][COLOR=#008080]StringFormatFlags[/COLOR][/SIZE][SIZE=2].DirectionVertical; [/SIZE][/FONT][FONT=Courier New][/LEFT]
[/LEFT]

[/FONT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008000]//Направление: вертикально[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][/LEFT]

[/COLOR][/SIZE][LEFT][SIZE=2]System.Drawing.[/SIZE][SIZE=2][COLOR=#008080]SolidBrush[/COLOR][/SIZE][SIZE=2] drawBrush = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] System.Drawing.[/SIZE][SIZE=2][COLOR=#008080]SolidBrush[/COLOR][/SIZE][SIZE=2](System.Drawing.[/SIZE][SIZE=2][COLOR=#008080]Color[/COLOR][/SIZE][SIZE=2].Black);[/SIZE]
[/FONT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008000]//Создаём кисть[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][/LEFT]

[/COLOR][/SIZE][LEFT][SIZE=2]gdiObj.DrawString([/SIZE][SIZE=2][COLOR=#800000]"My text"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Font[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"Times New Roman"[/COLOR][/SIZE][SIZE=2], 56F), drawBrush, [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]PointF[/COLOR][/SIZE][SIZE=2](56, 67), strFormat);[/SIZE][/LEFT]

[/FONT][LEFT][SIZE=2][FONT=Courier New][COLOR=#008000]//..рисуем..[/COLOR][/FONT][/SIZE][SIZE=2][FONT=Courier New][COLOR=#008000][/LEFT]

[/COLOR][/FONT][/SIZE][LEFT][SIZE=2][FONT=Courier New]}[/FONT][/SIZE][/LEFT]


Можно использовать технологию антиалиасинга для отрисовки текста:[/LEFT]
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]private [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Form1_Paint([/SIZE][SIZE=2][COLOR=#0000ff]object[/COLOR][/SIZE][SIZE=2] sender, [/SIZE][SIZE=2][COLOR=#008080]PaintEventArgs[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] e)[/FONT][/SIZE][SIZE=2]
[LEFT][FONT=Courier New]{[/FONT][/LEFT]

[/SIZE][LEFT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008080]Graphics[/COLOR][/SIZE][SIZE=2] gdiObj = e.Graphics; [/SIZE][SIZE=2][COLOR=#008000]//получаем GDI+ объект формы[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000][/LEFT]

[/COLOR][/SIZE][/FONT][LEFT][FONT=Courier New][SIZE=2][COLOR=#008080]StringFormat[/COLOR][/SIZE][SIZE=2] strFormat = [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]StringFormat[/COLOR][/SIZE][SIZE=2](); [/SIZE][SIZE=2][COLOR=#008000]//Создаём форматер текста[/COLOR][/SIZE][/FONT]
[SIZE=2][FONT=Courier New]strFormat.FormatFlags = [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]StringFormatFlags[/COLOR][/SIZE][SIZE=2].DirectionVertical; [/SIZE][SIZE=2][COLOR=#008000]//Направление: вертикально[/COLOR][/SIZE][/FONT][/LEFT]

[FONT=Courier New][SIZE=2][COLOR=#008000]
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]System.Drawing.[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]SolidBrush[/COLOR][/SIZE][SIZE=2] drawBrush = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] System.Drawing.[/SIZE][SIZE=2][COLOR=#008080]SolidBrush[/COLOR][/SIZE][SIZE=2](System.Drawing.[/SIZE][SIZE=2][COLOR=#008080]Color[/COLOR][/SIZE][SIZE=2].Black); [/SIZE][SIZE=2][COLOR=#008000]//Создаём кисть[/COLOR][/SIZE][/FONT]

[FONT=Courier New][SIZE=2][COLOR=#008000]
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]gdiObj.TextRenderingHint = System.Drawing.Text.[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]TextRenderingHint[/COLOR][/SIZE][SIZE=2].AntiAlias; [/SIZE][SIZE=2][COLOR=#008000]//в System.Drawing.Text.TextRenderingHint есть куча опций[/COLOR][/SIZE][/FONT]

[FONT=Courier New][SIZE=2][COLOR=#008000]
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]gdiObj.DrawString([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#800000]"My text"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Font[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"Times New Roman"[/COLOR][/SIZE][SIZE=2], 56F), drawBrush, [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2][COLOR=#008080]PointF[/COLOR][/SIZE][SIZE=2](56, 67), strFormat); [/SIZE][SIZE=2][COLOR=#008000]//..рисуем..[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008000]

[/COLOR][/SIZE][/FONT][LEFT][FONT=Courier New][SIZE=2]}[/SIZE][/FONT][/LEFT]

[/LEFT]


[LEFT]Ну и на всякий случай, получим список установленных в системе шрифтов:[/LEFT]
 
Код:
[LEFT][FONT=Courier New][SIZE=2][COLOR=#008080]FontFamily[/COLOR][/SIZE][SIZE=2] fonts = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] System.Drawing.Text.[/SIZE][SIZE=2][COLOR=#008080]InstalledFontCollection[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]().Families;[/FONT][/SIZE]

[/LEFT]

[SIZE=2]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#008080]FontFamily[/COLOR][/SIZE][SIZE=2] instFont [/SIZE][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] fonts)[/FONT][/SIZE]

[SIZE=2]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Console[/COLOR][/SIZE][SIZE=2].WriteLine(instFont.Name);[/SIZE][/FONT]




[/SIZE]
[/LEFT]
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
[SIZE=2][LEFT]Что касается сериализации объектов:
http://forum.codenet.ru/showthread.php?t=26945[/SIZE][/LEFT]
273
28 июля 2006 года
3A3-968M
1.2K / / 22.12.2005
Работа с протоколами SMTP и POP3:
http://forum.codenet.ru/showthread.php?t=26727
273
10 августа 2006 года
3A3-968M
1.2K / / 22.12.2005
Доступ к COM-порту в Microsoft .NET Framework 1.x/2.x можно реализовать через WinAPI функцию CreateFile. Смотрим в Platform SDK и пишем обёртку в C#:
 
Код:
[SIZE=2][FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]DllImport[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"kernel32.dll"[/COLOR][/SIZE][SIZE=2], SetLastError = [/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]extern [/COLOR][/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] CreateFile([/SIZE][SIZE=2][COLOR=#008080]String[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] lpFileName,[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080] UInt32[/COLOR][/SIZE][SIZE=2] dwDesiredAccess, [/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] dwShareMode,[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080] IntPtr[/COLOR][/SIZE][SIZE=2] lpSecurityAttributes, [/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] dwCreationDisposition,[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080] UInt32[/COLOR][/SIZE][SIZE=2] dwFlagsAndAttributes, [/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] hTemplateFile);
[/SIZE][/FONT]

Для чтения/записи данных порта используются WriteFile и ReadFile, для которых нужно передавать описатель, полученный функцией CreateFile (которая инициирует открытие порта):
Код:
[SIZE=2][FONT=Courier New][SIZE=2][[/SIZE][SIZE=2][COLOR=#008080]DllImport[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"kernel32.dll"[/COLOR][/SIZE][SIZE=2], SetLastError = [/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][SIZE=2])]
[/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]extern [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Boolean[/COLOR][/SIZE][SIZE=2] ReadFile([/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] hFile, [/SIZE]
  [SIZE=2][COLOR=#0000ff]out [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Byte[/COLOR][/SIZE][SIZE=2][] [/SIZE][SIZE=2]lpBuffer, [/SIZE]
[SIZE=2][COLOR=#008080] UInt32[/COLOR][/SIZE][SIZE=2] nNumberOfBytesToRead,
[/SIZE][SIZE=2][COLOR=#0000ff] out [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][SIZE=2] nNumberOfReadedBytes, [/SIZE]
  [SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] lpOverlapped);[/SIZE]
 
[SIZE=2][SIZE=2][[/SIZE][SIZE=2][COLOR=#008080]DllImport[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"kernel32.dll"[/COLOR][/SIZE][SIZE=2], SetLastError = [/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][SIZE=2])]
[/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]extern [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Boolean[/COLOR][/SIZE][SIZE=2] WriteFile([/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] fFile, [/SIZE][SIZE=2][COLOR=#008080]Byte[/COLOR][/SIZE][SIZE=2][] lpBuffer, [/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][SIZE=2] nNumberOfBytesToWrite,
[/SIZE][SIZE=2][COLOR=#0000ff]out [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][SIZE=2] lpNumberOfBytesWritten, [/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] lpOverlapped);
[/SIZE][/SIZE][/FONT][/SIZE][FONT=Courier New][SIZE=2]
[/SIZE][/FONT]


И ещё понадобяться парочка констант:
 
Код:
[FONT=Courier New][SIZE=2][COLOR=#0000ff]const [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Int32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] WIN32_INVALID_HANDLE_VALUE = -1;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]const [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] WIN32_FILE_FLAG_OVERLAPPED = 0x40000000;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]const [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] WIN32_OPEN_EXISTING = 3;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]const [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] WIN32_GENERIC_READ = 0x80000000;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]const [/COLOR][/SIZE][SIZE=2][COLOR=#008080]UInt32[/COLOR][/SIZE][SIZE=2] WIN32_GENERIC_WRITE = 0x40000000;
[/SIZE][/FONT]


Для того, чтобы закрыть порт, нужно уничтожить описатель, используем WinAPI-функцию CloseHandle:
 
Код:
[SIZE=2][FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]DllImport[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"kernel32.dll"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]extern [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Boolean[/COLOR][/SIZE][SIZE=2] CloseHandle([/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] hHandle);
[/SIZE][/FONT]


И самый простейший пример
Код:
[FONT=Courier New][SIZE=2][COLOR=#008000]//открываем порт
[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] hPort = CreateFile([/SIZE][SIZE=2][COLOR=#800000]"COM1:"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New], WIN32_GENERIC_READ | WIN32_GENERIC_WRITE, 0,[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2].Zero, WIN32_OPEN_EXISTING, WIN32_FILE_FLAG_OVERLAPPED, [/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Zero);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][SIZE=2] (hPort != ([/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2])WIN32_INVALID_HANDLE_VALUE) [/SIZE][SIZE=2][COLOR=#008000]//проверяем на ошибку
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]{[/FONT]
[/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//пишем/читаем данные порта, например[/FONT]
[/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] b ={ 1, 2, 3 };[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2] count = ([/SIZE][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])b.Length, sent = 0;[/FONT]
[FONT=Courier New]WriteFile(hPort, b, count, [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]out[/COLOR][/SIZE][SIZE=2] sent, [/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2].Zero); [/SIZE][SIZE=2][COLOR=#008000]//записали в порт
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]}[/FONT]
[FONT=Courier New]CloseHandle(hPort); [/FONT][/SIZE][SIZE=2][COLOR=#008000][FONT=Courier New]//закрываем порт[/FONT]
[/COLOR][/SIZE]

Более подробно можно почитать здесь:
http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/#contents
273
13 августа 2006 года
3A3-968M
1.2K / / 22.12.2005
На некоторых ОС семейства Windows, я заметил, что .NET-приложения (даже обычная форма с кнопочкой) занимают много памяти во время выполнения. Но это может происходить и не только с .NET-приложениями. Некоторые проги, написанные на Delphi с использованием VCL тоже отъедали памяти явно больше чем надо. Это связано с тем, что ОС резервирует дополнительную память на процесс. Спасёт в этом случае только WinAPI, используем функцию из kernel32.dll под названием SetProcessWorkingSetSize. Её можно использовать в Native-приложениях после освобождения больших объёмов памяти (удаление строк, массивов). В случае программ на C# создаём обёртку для функции и вызываем в самом начале программы:
 
Код:
[SIZE=2][FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]DllImport[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"kernel32.dll"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]extern [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]bool[/COLOR][/SIZE][SIZE=2] SetProcessWorkingSetSize([/SIZE][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] handle,[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] minimumWorkingSetSize, [/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] maximumWorkingSetSize);
[/SIZE][/FONT]

И вызов:
 
Код:
[FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] args)[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]IntPtr[/COLOR][/SIZE][SIZE=2] currentProcessHandle = System.Diagnostics.[/SIZE][SIZE=2][COLOR=#008080]Process[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].GetCurrentProcess().Handle;[/FONT]
[FONT=Courier New]SetProcessWorkingSetSize(currentProcessHandle, -1, -1);[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]
273
13 августа 2006 года
3A3-968M
1.2K / / 22.12.2005
Может появиться необходимость преобразовать число к какой-либо системе исчисления. Вот решение:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]public [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]enum [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Base[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]{HEX=16, BIN=2, OCT=8};[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2] ConvertToBase([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] value, [/SIZE][SIZE=2][COLOR=#008080]Base[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] toBase)[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff] return [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Convert[/COLOR][/SIZE][SIZE=2].ToString(value, ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])toBase);[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]
273
12 сентября 2006 года
3A3-968M
1.2K / / 22.12.2005
Хотите создать собственный класс для создания массива без System.Array?? Вот ответ:
http://sources.codenet.ru/file/1053/Arrays.cs
Предложенные классы работают по технологии связанных списков. Имеется простая система кэширования элементов для быстрого доступа.
273
21 октября 2006 года
3A3-968M
1.2K / / 22.12.2005
Если нужно узнать, на какой версии .NET Framework собрана сборка, делаем так:
 
Код:
[SIZE=2][COLOR=#008080][FONT=Courier New]Assembly[/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2] currentAssembly = [/SIZE][SIZE=2][COLOR=#008080]Assembly[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].GetEntryAssembly();[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Console[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].WriteLine([/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]String[/COLOR][/SIZE][SIZE=2].Concat([/SIZE][SIZE=2][COLOR=#800000]".NET Framework version dependency: "[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New], currentAssembly.ImageRuntimeVersion));[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Console[/COLOR][/SIZE][SIZE=2].ReadKey();
[/SIZE][/FONT]
273
21 ноября 2006 года
3A3-968M
1.2K / / 22.12.2005
При помощи защищённого метода MemberwiseClone можно создавать копии. Но эта функция выполняет лишь поверхностное копирование - т.е. создаётся новая копия экземпляра но все ссылки полей (если это поля классов, передаваемых по ссылке) нового экземпляра ссылаются на те же объекты, что и в оригинале. Поэтому изменение состояний объектов по ссылке в первом классе также отобразяться и во втором. Глубокое копирование предназначено для создания полной и независимой копии.
При помощи этой функции можно выполнять поверхностное копирование:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]static [/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New]T CreateShallowCopy<T>(T o)[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]  MethodInfo[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] memberwiseClone = o.GetType().[/FONT][FONT=Courier New]GetMethod([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#800000]"MemberwiseClone"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].Instance | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].NonPublic);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  return [/COLOR][/SIZE][SIZE=2](T)memberwiseClone.Invoke(o, [/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]);[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Эта функция выполняет глубокое копирование:
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]static [/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New]T CreateDeepCopy<T>(T o)[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]  T copy = CreateShallowCopy(o);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  foreach[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]FieldInfo[/COLOR][/SIZE][SIZE=2] f [/SIZE][SIZE=2][COLOR=#0000ff]in [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]typeof[/COLOR][/SIZE][SIZE=2](T).GetFields([/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].Instance | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].NonPublic | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Public))[/FONT]
[FONT=Courier New]  {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    object[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] original = f.GetValue(o);[/FONT]
[FONT=Courier New]    f.SetValue(copy, CreateDeepCopy(original));[/FONT]
[FONT=Courier New]  }[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] copy;[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Обе функции универсальны и подходят абсолютно для любого типа.
273
04 января 2007 года
3A3-968M
1.2K / / 22.12.2005
[SIZE=2]Если необходимо вызывать native-функции из Dll, имя которой может быть на этапе компиляции не ивзестно, или нельзя на этапе компиляции определить сигнатуру native-функции в этой библиотеке, тогда вот решение:[/SIZE]
[SIZE=2][FONT=Courier New]http://sources.codenet.ru/download/1236/PlatformInvoker.html[/FONT][/SIZE]

Класс PlatformInvoker позволяет вызывать из неуправляемых библиотек любые Native-функции, сигнатуру можно конструировать во время выполнения. Класс PlatformInvoker2 оборачивает native-функцию в делегат, что позволяет вызывать native-функцию со строгим контролем типов на этапе компиляции.
273
08 января 2007 года
3A3-968M
1.2K / / 22.12.2005
К сожалению, класс System.Windows.Forms.TreeView не предоставляет стандартной функциональности для сортировки узлов (в отличие от аналогичного Delphi-компонента в VCL.NET). Эта функция отданна программисту. Но вручную производить перебор узлов не нужно. Необходимо всего лишь предоставить алгоритм сортиовки классу TreeView и всё. Для этого нужно передать ссылку в свойство TreeView.TreeViewNodeSorter на реализацию интерфейса IComparable. Вот моя реализация для сортировки по алфавиту с возможностью восходящей и нисходящей сортировки:
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]internal [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]class [/COLOR][/SIZE][SIZE=2][COLOR=#008080]AlphabetNodeSorter[/COLOR][/SIZE][SIZE=2] : [/SIZE][SIZE=2][COLOR=#008080]IComparer[/COLOR][/SIZE][SIZE=2]<[/SIZE][SIZE=2][COLOR=#008080]TreeNode[/COLOR][/SIZE][SIZE=2]>, System.Collections.[/SIZE][SIZE=2][COLOR=#008080]IComparer[/COLOR][/SIZE][/FONT]
[SIZE=2][FONT=Courier New]{[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] private [/COLOR][/SIZE][SIZE=2][COLOR=#008080]SortOrder[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] m_sort;[/FONT][/SIZE]
 
[FONT=Courier New][SIZE=2][COLOR=#0000ff] public[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] AlphabetNodeSorter()[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] {[/FONT][/SIZE]
[SIZE=2][FONT=Courier New]   m_sort = [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]SortOrder[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Ascending;[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] }[/FONT][/SIZE]
 
[FONT=Courier New][SIZE=2][COLOR=#0000ff] public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] Compare([/SIZE][SIZE=2][COLOR=#008080]TreeNode[/COLOR][/SIZE][SIZE=2] tx, [/SIZE][SIZE=2][COLOR=#008080]TreeNode[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] ty)[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] {[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   int[/COLOR][/SIZE][SIZE=2] result = [/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2].Compare(ty.Text, tx.Text, [/SIZE][SIZE=2][COLOR=#008080]StringComparison[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].OrdinalIgnoreCase);[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   if[/COLOR][/SIZE][SIZE=2] (m_sort == [/SIZE][SIZE=2][COLOR=#008080]SortOrder[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Ascending) result = -result;[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] result;[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] }[/FONT][/SIZE]
 
[FONT=Courier New][SIZE=2][COLOR=#0000ff] int[/COLOR][/SIZE][SIZE=2] System.Collections.[/SIZE][SIZE=2][COLOR=#008080]IComparer[/COLOR][/SIZE][SIZE=2].Compare([/SIZE][SIZE=2][COLOR=#0000ff]object[/COLOR][/SIZE][SIZE=2] x, [/SIZE][SIZE=2][COLOR=#0000ff]object[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] y)[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] {[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#008080]   TreeNode[/COLOR][/SIZE][SIZE=2] tx = x [/SIZE][SIZE=2][COLOR=#0000ff]as[/COLOR][/SIZE][SIZE=2][COLOR=#008080]TreeNode[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New];[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#008080]   TreeNode[/COLOR][/SIZE][SIZE=2] ty = y [/SIZE][SIZE=2][COLOR=#0000ff]as[/COLOR][/SIZE][SIZE=2][COLOR=#008080]TreeNode[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New];[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Compare(tx, ty);[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] }[/FONT][/SIZE]
 
[FONT=Courier New][SIZE=2][COLOR=#0000ff] public[/COLOR][/SIZE][SIZE=2][COLOR=#008080]SortOrder[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Sort[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] {[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   get[/COLOR][/SIZE][SIZE=2] { [/SIZE][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] m_sort; }[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   set[/COLOR][/SIZE][SIZE=2] { m_sort = [/SIZE][SIZE=2][COLOR=#0000ff]value[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]; }[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] }[/FONT][/SIZE]
[SIZE=2][FONT=Courier New]}[/FONT][/SIZE]

Теперь перед добавлением узлов установим свойство TreeViewNodeSorter:
 
Код:
[SIZE=2][FONT=Courier New]treeView.TreeViewNodeSorter = [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]AlphabetNodeSorter[/COLOR][/SIZE][SIZE=2]();[/SIZE][/FONT]

Теперь вновь добавленные узлы будут автоматически сортироваться.
14K
05 февраля 2007 года
Freddy
5 / / 13.12.2005
Поскольку по работе приходиться разбираться в разных вещах, то часто приходиться писать разные маленькие програмки.
Как правело они нужны для того, чтоб разобраться в том или ином вопросе...
Вот так и появился этот конвертор.
Конечно можно его поместить в раздел исходники, но и на форуме иму будет не скучно.
Я писл его в borland, но поскольку он консольный то собереться в любой среде.
Можно долго рассказывать о маленькой програмке, но врятли это поможет.
Как говориться если есть вопросы то по почте будет проще и мне и вам...
Ниже сам текст...
using System;
using System.IO;
namespace convert
{
class Application
{
/// The main entry point for the application.
[STAThread]
static void Main(string[] args)
{
Convert cnt =new Convert();
if (args.Length == 0)
{
Help help = new Help();
help =null;
cnt =null;
return;
}// help
if (args[0] =="/b")
{
cnt.EncodeTooBase64(args[1]);
cnt =null;
return;
}// convert too Base
if (args[0] =="/s")
{
cnt.DecodeTooStream(args[1]);
cnt =null;
return;
}// convert too stream
return;
}
}// end class

class Convert
{
// constructor
public Convert()
{

}
public void EncodeTooBase64(string filename) {
FileStream inFile;
byte[] binaryData;

try {
inFile = new FileStream(filename,
System.IO.FileMode.Open,
System.IO.FileAccess.Read);
binaryData = new Byte[inFile.Length];
long bytesRead = inFile.Read(binaryData, 0,
(int)inFile.Length);
inFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or reading from it.
System.Console.WriteLine("{0}", exp.Message);
return;
}

// Convert the binary input into Base64 UUEncoded output.
string base64String;
try {
base64String =
System.Convert.ToBase64String(binaryData,
0,
binaryData.Length);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Binary data array is null.");
return;
}

// Write the UUEncoded version to the output file.
System.IO.StreamWriter outFile;
try {
outFile = new System.IO.StreamWriter("cert.data",
false,
System.Text.Encoding.ASCII);
outFile.Write(base64String);
outFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or writing to it.
System.Console.WriteLine("{0}", exp.Message);
}
}

public void DecodeTooStream(string filename) {
System.IO.StreamReader inFile;
string base64String;

try {
char[] base64CharArray;
inFile = new System.IO.StreamReader(filename,
System.Text.Encoding.ASCII);
base64CharArray = new char[inFile.BaseStream.Length];
inFile.Read(base64CharArray, 0, (int)inFile.BaseStream.Length);
base64String = new string(base64CharArray);
}
catch (System.Exception exp) {
// Error creating stream or reading from it.
System.Console.WriteLine("{0}", exp.Message);
return;
}

// Convert the Base64 UUEncoded input into binary output.
byte[] binaryData;
try {
binaryData =
System.Convert.FromBase64String(base64String);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Base 64 string is null.");
return;
}
catch (System.FormatException) {
System.Console.WriteLine("Base 64 string length is not " +
"4 or is not an even multiple of 4." );
return;
}

// Write out the decoded data.
System.IO.FileStream outFile;
try {
outFile = new System.IO.FileStream("cert.cer",
System.IO.FileMode.Create,
System.IO.FileAccess.Write);
outFile.Write(binaryData, 0, binaryData.Length);
outFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or writing to it.
System.Console.WriteLine("{0}", exp.Message);
}
}
}// convert
class Help
{
public Help()
{
System.Console.WriteLine("В ведите /s | имя файла\n");
System.Console.WriteLine("\t/b | Имя файла\n");
System.Console.WriteLine("\t /s конвертировать в строку\n\t /b Конвертировать в Bаse64");
}

}//Help
}
273
21 февраля 2007 года
3A3-968M
1.2K / / 22.12.2005
Если необходимо получить процент занятости процессора, то предлагаю своё решение. Обратите внимание, что такую информацию можно получить без обращения к WMI или Platform Invoke, код 100% managed.
Вот он:
 
Код:
[SIZE=2][FONT=Courier New]System.Diagnostics.[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]PerformanceCounterCategory[/COLOR][/SIZE][SIZE=2] cat = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] System.Diagnostics.[/SIZE][SIZE=2][COLOR=#008080]PerformanceCounterCategory[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"Processor"[/COLOR][/SIZE][SIZE=2]); [/SIZE][SIZE=2][COLOR=#008000]//Получаем все счётчики процессора
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]System.Diagnostics.[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]PerformanceCounter[/COLOR][/SIZE][SIZE=2] procPerf = cat.GetCounters([/SIZE][SIZE=2][COLOR=#800000]"_Total"[/COLOR][/SIZE][SIZE=2])[0]; [/SIZE][SIZE=2][COLOR=#008000]//Данный экземпляр счётчика выдаёт данные о нагрузке
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New])[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]  MessageBox[/COLOR][/SIZE][SIZE=2].Show([/SIZE][SIZE=2][COLOR=#800000]"Processor Busy: "[/COLOR][/SIZE][SIZE=2] + procPerf.NextValue().ToString()); [/SIZE][SIZE=2][COLOR=#008000]//Получаем результат
[/COLOR][/SIZE][/FONT]
273
26 февраля 2007 года
3A3-968M
1.2K / / 22.12.2005
Метод Type.GetInterfaces() возвращает список как реализованных интерфейсов, так и унаследованных от своих предков. Вследствие чего информация о типе является не совсем верной. Это метод позволяет получить только реализованные интерфейсы:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]internal [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#008080]Type[/COLOR][/SIZE][SIZE=2][] GetImplementation([/SIZE][SIZE=2][COLOR=#008080]Type[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] target)[/FONT][/SIZE]
[SIZE=2][FONT=Courier New]{[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#008080] List[/COLOR][/SIZE][SIZE=2]<[/SIZE][SIZE=2][COLOR=#008080]Type[/COLOR][/SIZE][SIZE=2]> result = [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]List[/COLOR][/SIZE][SIZE=2]<[/SIZE][SIZE=2][COLOR=#008080]Type[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]>();[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#008080]Type[/COLOR][/SIZE][SIZE=2] iface [/SIZE][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] target.GetInterfaces())[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] {[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#008080]   InterfaceMapping[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] map = target.GetInterfaceMap(iface);[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]   if[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] (map.TargetMethods[0].DeclaringType.Equals(target)) result.Add(iface);[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] }[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] result.ToArray();[/FONT][/SIZE]
[SIZE=2][FONT=Courier New]}[/FONT][/SIZE]

Большое спасибо DotNetHeaven'у за подсказку (оригинальное сообщение: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1266165&SiteID=1)
273
05 мая 2007 года
3A3-968M
1.2K / / 22.12.2005
Выключить комп, завершить сеанс и перзагрузиться под управлением Windows программно из кода на C# очень просто и без использования Platform Invoke и WinAPI:
http://sources.codenet.ru/file/1391/WindowsSessionWorker.cs
273
14 мая 2007 года
3A3-968M
1.2K / / 22.12.2005
Простейший пример выборки из массива строк по условию:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]var [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2]names = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2][] { [/SIZE][SIZE=2][COLOR=#a31515]"One"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515]"Two"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515]"Three"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515]"Four"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]};[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]var [/COLOR][/SIZE][SIZE=2]result = [/SIZE][SIZE=2][COLOR=#0000ff]from [/COLOR][/SIZE][SIZE=2]c [/SIZE][SIZE=2][COLOR=#0000ff]in [/COLOR][/SIZE][SIZE=2]names [/SIZE][SIZE=2][COLOR=#0000ff]where[/COLOR][/SIZE][SIZE=2] c[0] != [/SIZE][SIZE=2][COLOR=#a31515]'T' [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]select[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] c;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]foreach[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]var [/COLOR][/SIZE][SIZE=2]item [/SIZE][SIZE=2][COLOR=#0000ff]in [/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]result)[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#2b91af]Console[/COLOR][/SIZE][SIZE=2].WriteLine(item);
[/SIZE][/FONT]
5
06 сентября 2008 года
hardcase
4.5K / / 09.08.2005
Снимок экрана можно сделать таким вот методом:
 
Код:
public static Bitmap MakeScreenShot(Screen screen) {
    Bitmap bitmap = new Bitmap(screen.WorkingArea.Width, screen.WorkingArea.Height);
    using (Graphics gfx = Graphics.FromImage(bitmap)) {
        gfx.CopyFromScreen(screen.WorkingArea.X, screen.WorkingArea.Y, 0, 0, new Size(bitmap.Width, bitmap.Height));
    }
    return bitmap;
}
Вызывать например так:
 
Код:
Bitmap screen_shot = MakeScreenShot(Screen.PrimaryScreen);
33K
23 сентября 2008 года
Gertzog
2 / / 09.11.2007
Цитата: 3A3-968M
При помощи защищённого метода MemberwiseClone можно создавать копии. Но эта функция выполняет лишь поверхностное копирование - т.е. создаётся новая копия экземпляра но все ссылки полей (если это поля классов, передаваемых по ссылке) нового экземпляра ссылаются на те же объекты, что и в оригинале. Поэтому изменение состояний объектов по ссылке в первом классе также отобразяться и во втором. Глубокое копирование предназначено для создания полной и независимой копии.
При помощи этой функции можно выполнять поверхностное копирование:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]static [/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New]T CreateShallowCopy<T>(T o)[/FONT]
[FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]  MethodInfo[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] memberwiseClone = o.GetType().[/FONT][FONT=Courier New]GetMethod([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#800000]"MemberwiseClone"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].Instance | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].NonPublic);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  return [/COLOR][/SIZE][SIZE=2](T)memberwiseClone.Invoke(o, [/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]);[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Эта функция выполняет глубокое копирование:
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]static [/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New]T CreateDeepCopy<T>(T o)[/FONT]
[FONT=Courier New]{[/FONT]
[FONT=Courier New]  T copy = CreateShallowCopy(o);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  foreach[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]FieldInfo[/COLOR][/SIZE][SIZE=2] f [/SIZE][SIZE=2][COLOR=#0000ff]in [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]typeof[/COLOR][/SIZE][SIZE=2](T).GetFields([/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].Instance | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][SIZE=2].NonPublic | [/SIZE][SIZE=2][COLOR=#008080]BindingFlags[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Public))[/FONT]
[FONT=Courier New]  {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    object[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] original = f.GetValue(o);[/FONT]
[FONT=Courier New]    f.SetValue(copy, CreateDeepCopy(original));[/FONT]
[FONT=Courier New]  }[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] copy;[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Обе функции универсальны и подходят абсолютно для любого типа.



Признаться, у меня это не сработало.

Контрпример:

 
Код:
List<State> ls = new List<State>(10);
            ls.Add(new State(1, 3, 3, 6, 1));
            ls.Add(new State(1, 2, 3));
            ls.Add(new State(4, 5, 6));
            List<State> LS = Util.General.CreateDeepCopy(ls);
            ls[0][0] = 89;
            LS[0][0] = 101;


где

Код:
public class State
    {
        public State(int size)
        {
            m_Contents = new int[size];
            m_Size = size;
        }

        public State(params int[] values)
        {
            m_Contents = new int[values.Length];
            for (int i = 0; i < values.Length; ++i )
            {
                m_Contents = values;
            }
        }

        public int this[int indx]
        {
            get { return m_Contents[indx]; }
            set { m_Contents[indx] = value; }
        }

        public int Size
        {
            get { return m_Size; }
        }

        int[] m_Contents;
        int m_Size;


Если в чистом виде юзать предложенные функции, то, случае нулевой ссылки, выбрасывается исключение
System.NullReferenceException was unhandled
Message="В экземпляре объекта не задана ссылка на объект."
Source="ServiceAllocator"

Поэтому CreateDeepCopy был защищён от нулевой ссылки обычным условием.

Код:
if (o != null)
            {
                T copy = CreateShallowCopy(o);
                foreach (FieldInfo f in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                {
                    object original = f.GetValue(o);
                    f.SetValue(copy, CreateDeepCopy(original));
                }
                return copy;
            }
            return default(T);


Как, всё же, осуществить глубокое копирование?
5
23 сентября 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Gertzog
Признаться, у меня это не сработало.
.....
Как, всё же, осуществить глубокое копирование?


Все верно. Код моего коллеги не учитывает особый статус массивов CLR.
Попробуйте следующий код

Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ConsoleApplication8 {

    using CopyingState = System.Collections.Generic.Dictionary<object, object>;

    public sealed class CopyHelper {

        private static readonly Type array_type = typeof(Array);

        private static readonly MethodInfo memberwise_clone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);

        private static void MakeArrayRowDeepCopy(CopyingState state, Array array, int[] indices, int rank) {
            int next_rank = rank + 1;
            int upper_bound = array.GetUpperBound(rank);

            while (indices[rank] <= upper_bound) {
                object value = array.GetValue(indices);
                if (!object.ReferenceEquals(value, null))
                    array.SetValue(CreateDeepCopyInternal(state, value), indices);

                if (next_rank < array.Rank)
                    MakeArrayRowDeepCopy(state, array, indices, next_rank);

                indices[rank] += 1;
            }
            indices[rank] = array.GetLowerBound(rank);
        }

        private static Array CreateArrayDeepCopy(CopyingState state, Array array) {
            Array result = (Array)array.Clone();
            int[] indices = new int[result.Rank];
            for (int rank = 0; rank < indices.Length; ++rank)
                indices[rank] = result.GetLowerBound(rank);
            MakeArrayRowDeepCopy(state, result, indices, 0);
            return result;
        }

        private static object CreateShallowCopyInternal(object o) {
            if (o is Array)
                return (o as Array).Clone();
            else if (o is string)
                return string.Copy((string)o);            
            return memberwise_clone.Invoke(o, null);
        }

        public static T CreateShallowCopy<T>(T o) {
            object input = (object)o;
            if (object.ReferenceEquals(input, null))
                return o;
            return (T)CreateShallowCopyInternal(input);
        }

        private static object CreateDeepCopyInternal(CopyingState state, object o) {
            object exist_object;
            if (state.TryGetValue(o, out exist_object))
                return exist_object;

            if (o is Array) {
                object array_copy = CreateArrayDeepCopy(state, (Array)o);
                state[o] = array_copy;
                return array_copy;
            } else if (o is string) {
                object string_copy = string.Copy((string)o);
                state[o] = string_copy;
                return string_copy;
            } else {                                                
                Type o_type = o.GetType();
                if (o_type.IsPrimitive)                    
                    return o;
                object copy = memberwise_clone.Invoke(o, null);
                state[o] = copy;                
                foreach (FieldInfo f in o_type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) {
                    object original = f.GetValue(o);
                    if (!object.ReferenceEquals(original, null))
                        f.SetValue(copy, CreateDeepCopyInternal(state, original));
                }
                return copy;
            }
        }

        public static T CreateDeepCopy<T>(T o) {
            object input = (object)o;
            if (object.ReferenceEquals(o, null))
                return o;
            return (T)CreateDeepCopyInternal(new CopyingState(), input);
        }

    }

    class A {
        public A(string x) {
            this.x = x;
        }

        public readonly string x;

        public A a;
    }

    class Program {
        static void Main(string[] args) {
            A a1 = new A("qwret");
            a1.a = a1;

            A a2 = CopyHelper.CreateDeepCopy(a1);

            A a3 = CopyHelper.CreateShallowCopy(a1);


            Console.ReadKey();
        }
    }
}
5
16 февраля 2009 года
hardcase
4.5K / / 09.08.2005
[quote=NextTime]Как можно сделать, чтобы по CTRL+Break окно коносли не закрывалось?[/quote]В .NET есть соглашение о том, что Ctrl+Break нельзя перехватывать. Событие Console.CancelKeyPress отработает, но установить Cancel = true не выйдет - вылетает исключение.

В принципе можно написать хак, использующий отражение :
Код:
using System;
using System.Text;
using System.Reflection;

namespace ConsoleApplication11 {
    class Program {
        static void Main(string[] args) {
            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
            while (true) {
                Console.ReadLine();
            }
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) {
            Console.WriteLine(e.SpecialKey);
            FieldInfo cancel_field = e.GetType().GetField("_cancel", BindingFlags.Instance | BindingFlags.NonPublic);
            if (cancel_field != null)
                cancel_field.SetValue(e, true);
        }
    }
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог