.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. |