CLS-совместимая альтернатива для недвижимости ulong - PullRequest
3 голосов
/ 05 апреля 2011

Фон

Я пишу управляемый ассемблер x64 (который также является библиотекой), поэтому у него есть несколько классов, которые определяют 64-разрядное целочисленное свойство без знака для использования в качестве адресов и смещений.Некоторые из них являются смещениями файлов, другие - абсолютными адресами (относительно основной памяти), а другие - относительными виртуальными адресами.

Проблема

Я использую тип данных ulong для свойств в упомянутомсценарии, и это прекрасно работает.Однако такие свойства не соответствуют CLS.Я могу пометить их как [ClsCompliant(false)], но затем мне нужно предоставить CLS-совместимую альтернативу пользователям библиотеки.

Опции и вопросы

Некоторые предлагают предоставлениеальтернативное свойство с большим типом данных, но это не вариант, потому что нет большего целочисленного примитива со знаком, который мог бы содержать все значения от 0 до UInt64.MaxValue.

Я бы предпочел не отмечать весь мойсборка не совместима с CLS, поскольку в большинстве сценариев использования используются не все возможные значения до UInt64.MaxValue.Так, например, для Address я мог бы предоставить альтернативное свойство long AddressAlternative, которое принимает только положительные значения.Однако, что должно произойти, если Address содержит значение выше Int64.MaxValue.Должно ли AddressAlternative вызвать какое-то исключение?

И какое имя будет подходящим для AddressAlternative?

Если предоставить альтернативу для каждого использования ulong, это приведет ко многим «двойным» свойствам,Есть лучший способ сделать это?Обратите внимание, что не все случаи использования ulong свойств имеют одинаковую семантику, поэтому один struct не сможет его обрезать.

И, наконец, у меня одна и та же проблема соответствия CLS в параметрах конструктора.Так должен ли я предоставить альтернативную перегрузку, принимающую long для такого параметра?

Я не против ограничить использование (некоторых функций) библиотеки, когда она используется из контекста только CLS, есликак это может быть использовано в большинстве сценариев.

Ответы [ 2 ]

2 голосов
/ 05 апреля 2011

но если он представляет неподписанный адрес выше Int64.MaxValue

Вы используете неправильный тип, адреса должны храниться в IntPtr или UIntPtr.Просто ваша проблема нереальна.Если вы не можете позволить себе потерять один бит в UInt64, то вы слишком длинны для переполнения.Если это число представляет индекс, то обычный Int32 будет в порядке, двоичные объекты памяти .NET ограничены 2 гигабайтами, даже на 64-разрядной машине.

Если это адрес, то IntPtr подойдет дляочень и очень долгоДоступное в настоящее время оборудование находится на расстоянии 4,5 порядка от достижения этого предела.Чтобы приблизиться, потребуется очень радикальная модернизация оборудования, и у вас будут гораздо большие проблемы, о которых стоит беспокоиться, когда наступит этот день.Девяти эксабайт виртуальной памяти хватит всем, пока я не уйду на пенсию.

0 голосов
/ 16 апреля 2011

Microsoft определяет 64-битный адрес как Int64, а не UInt64, поэтому вы все равно можете быть CLS-совместимым.

Пожалуйста, обратитесь к http://msdn.microsoft.com/en-us/library/837ksy6h.aspx.

Что в основном говорит:

Конструктор IntPtr (Int64)

Инициализация новый экземпляр IntPtr с использованием указанный 64-битный указатель.

Параметры значение Тип: System.Int64 Указатель или дескриптор, содержащийся в 64-разрядном целом числе со знаком.

И да, я только что провел быстрое тестирование, и следующее работало нормально в проекте, ориентированном на x64 или Any CPU. Я поместил брекпойнт в код и осмотрел x. Однако, если он предназначен только для x86, он выдаст исключение.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr x = new IntPtr(long.MaxValue);
        }
    }
}

Но, если окажется, что вам действительно нужен этот дополнительный бит. Вы могли бы предоставить две библиотеки. Тот, который является CLS-совместимым и тот, который не - выбор пользователя. Этого можно достичь с помощью операторов #if и условных символов компиляции. Таким образом, вы можете определить одно и то же имя переменной, но с разными определениями. http://msdn.microsoft.com/en-us/library/4y6tbswk.aspx

...