我正在编写一个托管x64汇编程序(也是一个库),因此它有多个类,它们定义了一个无符号的64位整数属性,用作地址和偏移量。一些是文件偏移,另一些是绝对地址(相对于主存储器),另一些是相对虚拟地址。
我在上述场景中使用ulong
数据类型作为属性,这很好用。但是,此类属性不符合CLS。我可以将它们标记为[ClsCompliant(false)]
,但是我需要为库的用户提供符合CLS的替代方案。
某些suggest提供了具有更大数据类型的替代属性,但这不是一个选项,因为没有更大的有符号整数原语可以保存从0
到UInt64.MaxValue
的所有值
我宁愿不将整个程序集标记为非CLS兼容,因为在大多数使用方案中,并非使用最多UInt64.MaxValue
的所有可能值。因此,对于例如Address
我可以提供另一个long
属性AddressAlternative
,它只接受正值。但是,当Address
以某种方式包含高于Int64.MaxValue
的值时,会发生什么。 AddressAlternative
应该抛出一些例外吗?
AddressAlternative
的适当名称是什么?
为ulong
的每次使用提供替代方案将导致许多“双重”属性。有一个更好的方法吗?请注意,并非ulong
属性的所有用法都具有相同的语义,因此单个struct
不会删除它。
最后,我在构造函数参数中遇到了相同的CLS合规性问题。那么我应该为这样的参数提供接受long
的替代重载吗?
我不介意在从仅使用CLS的上下文中使用库时限制库的(某些功能)的使用,只要它可以在大多数情况下使用。
答案 0 :(得分:2)
但是它表示Int64.MaxValue
上方的无符号地址
您使用的是错误的类型,地址必须存储在IntPtr或UIntPtr中。你的问题是不现实的。如果您无法承受丢失UInt64中的单个位,那么您方式太接近溢出。如果这个数字代表一个索引,那么普通的Int32就可以了,.NET内存blob限制在2 GB,即使在64位机器上也是如此。
如果是地址,那么IntPtr将会很长时间没问题。目前可用的硬件距离达到该限制4.5个数量级。需要进行非常激烈的硬件重新设计才能接近,当有一天到来时,你会担心更大的问题。在我退休之前,每个人都有9 exabyte的虚拟内存。
答案 1 :(得分:0)
Microsoft将64位地址定义为Int64,而不是UInt64,因此您仍然可以符合CLS。
请参阅http://msdn.microsoft.com/en-us/library/837ksy6h.aspx。
基本上说:
IntPtr构造函数(Int64)
初始化 一个新的IntPtr实例使用 指定的64位指针。
参数 值 键入:System.Int64 包含在64位有符号整数中的指针或句柄。
是的,我刚做了一个快速测试,以下工作在针对x64或任何CPU的项目中都运行良好。我在代码中放置了一个brekpoint并检查了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