Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #66, МАЙ 2006 г.

.NET секретам

 

Спецвыпуск: Хакер, номер #066, стр. 066-058-2


Первая ошибка, которую выдал компилятор: PureComponents.NicePanel.Design\ActionMenuNative.cs(249): Небезопасный код может использоваться только при компиляции с параметром /unsafe.

В компоненте используются небезопасные конструкции, применяющие указатели. Как известно, указатели могут указывать на нераспределенную память или указывать совсем не туда, куда должен. Соответствующая ошибка программирования (в использовании указателей) довольно распространена, поэтому в .NET оставили лишь поддержку этой возможности (для случаев, где без указателей нельзя решить поставленную задачу).

Итак, нужно зайти в опции проекта и установить параметр Allow Unsafe Code Blocks = True. Затем еще раз делаем buid и видим, что компилятор выдал 58 ошибок.

Начнем с проблемы, которая ждала нас в методе PureComponents.NicePanel.NicePanel::OnPaintBackground(PaintEventArgs pevent). Компилятор сообщает об ошибке

cs(416): Оператор '+' не может применяться к операндам типа 'PureComponents.NicePanel.PanelHeaderSize' и 'PureComponents.NicePanel.PanelHeaderSize'

Посмотрев на PanelHeaderSize, обнаруживаем, что это enum (перечисление).

public enum PanelHeaderSize

{

Large = 40,

Medium = 24,

Small = 16

}

Вот уже становится понятно, что должно происходить сложение элементов перечисления, для чего в C# используется оператор (|). Заменив (+) на (|), мы избавляемся от девяти ошибок. Аналогичная ошибка есть в методе

PureComponents.NicePanel.Design.NicePanelDesigner::OnRemoveAutoScrollPanel(object sender, EventArgs e).

В этом же классе компилятор ругается в методе

OnAddAutoScrollPanel(object sender, EventArgs e) строка 345: Оператор '-' не может применяться к операндам типа 'int' и 'PureComponents.NicePanel.PanelHeaderSize'.

Вот как раз эта строка:

panel1.Height = (int)(((((PanelHeaderSize)this.m_NicePanel.Height) - this.m_NicePanel.Style.HeaderStyle.Size) - this.m_NicePanel.Style.FooterStyle.Size) - ((PanelHeaderSize)2));

Рассмотрим эту строку кода поближе. Во-первых, внимательно приглядываемся к приведению типа int к типу PanelHeaderSize: (PanelHeaderSize)this.m_NicePanel.Height. При этом происходит выравнивание к ближайшему элементу в перечислении PanelHeaderSize. К примеру, если Height будет равен 19-ти, то это преобразование округлит до PanelHeaderSize.Small(16). Если Height будет равен 21-му, преобразование округлит до PanelHeaderSize.Medium (24).

Таким преобразованием автор добился дискретности размера некоего окна, и поэтому размер окна в любом случае будет только одним из трех (40, 24, 16). В чем суть ошибки? Когда два enum'а участвуют в разности, результат автоматически преобразуется в тип int, и уже при следующем вычитании получается, что из объекта с типом int вычитается объект с типом PanelHeaderSize. Компилятор же видит несоответствие типов и выдает нам ошибку компиляции. Следовательно, для решения проблемы каждая разность должна быть выделена в отдельные скобки и результат разности должен быть приведен к типу PanelHeaderSize.

Назад на стр. 066-058-1  Содержание  Вперед на стр. 066-058-3