【问题标题】:CLS-compliant alternative for ulong property符合 CLS 的 ulong 属性替代方案
【发布时间】:2011-04-16 22:08:21
【问题描述】:

背景

我正在编写一个托管的 x64 汇编器(它也是一个库),因此它有多个类,这些类定义了一个无符号 64 位整数属性,用作地址和偏移量。有些是文件偏移,有些是绝对地址(相对于主内存),还有一些是相对虚拟地址。

问题

我对上述场景中的属性使用ulong 数据类型,这很好用。但是,此类属性不符合 CLS。我可以将它们标记为[ClsCompliant(false)],但我需要为图书馆的用户提供符合 CLS 的替代方案。

选项和问题

一些suggest 提供具有更大数据类型的替代属性,但这不是一个选项,因为没有更大的有符号整数原语可以保存从0UInt64.MaxValue 的所有值。

我宁愿不将我的整个程序集标记为不符合 CLS,因为在大多数使用场景中,并非所有可能的值都被使用到 UInt64.MaxValue。所以,例如Address 我可以提供一个替代的long 属性AddressAlternative,它只接受正值。但是,当Address 以某种方式包含高于Int64.MaxValue 的值时会发生什么。 AddressAlternative 应该抛出一些异常吗?

AddressAlternative 的合适名称是什么?

ulong 的每次使用提供替代方案将导致许多“双重”属性。有一个更好的方法吗?请注意,并非所有 ulong 属性的用法都具有相同的语义,因此单个 struct 不会削减它。

最后,我在构造函数参数中遇到了同样的 CLS 合规性问题。那么我应该为这样的参数提供一个接受long 的替代重载吗?

我不介意在仅用于 CLS 的上下文中限制库的(某些功能)的使用,只要它可以在大多数情况下使用。

【问题讨论】:

  • 您是否预计该库中有很多用户使用需要严格遵守 CLS 的语言?您有多少客户将使用不支持 ulong 的语言的库?
  • 您的评论“并非所有 ulong 属性的用法都具有相同的语义,因此单个结构不会削减它”似乎是一个可能的解决方案。比如说,如果偏移量和地址具有不同的语义,那么为什么不制作一个围绕 ulong 的 Offset 和 Address 结构,它可以强制执行您想要的任何语义?你甚至可以有重载的操作符,这样地址 + 地址是非法的,但地址 + 偏移量会生成一个新地址。
  • 它将是开源的,因此这取决于严格的 CLS 语言的可用性。编写库时,CLS 合规性非常高advised
  • 确实,它回答了我的一些问题。但这不会导致大量代码重复吗?我知道使用 ulong 的至少三种不同的语义类型。然后我将问题转移到新的 Address 类型:它将包含一些可以返回当前地址值的属性,但是当它表示 Int64.MaxValue 以上的无符号地址时,替代属性应该返回什么?
  • @Virtlink:我认为正如 Eric 所建议的那样,使用“语义结构”是这里的方法。也就是说,我认为您根本不应该对它们有任何属性-只需提供转换运算符:从ulongdecimal 的显式转换,以及到ulongdecimal 的隐式转换。为什么decimal?它是唯一覆盖ulong 整个范围且不损失精度的其他标准类型,您可以轻松地检查没有小数部分。

标签: c# cls-compliant uint64


【解决方案1】:

但是当它代表一个高于 Int64.MaxValue 的无符号地址时

您使用了错误的类型,地址必须存储在 IntPtr 或 UIntPtr 中。你的问题不可能是现实的。如果您无法承受丢失 UInt64 中的单个位,那么您 方式 太接近溢出了。如果这个数字代表一个索引,那么一个普通的 Int32 就可以了,.NET 内存 blob 被限制为 2 GB,即使在 64 位机器上也是如此。

如果它是一个地址,那么 IntPtr 会在很长一段时间内都可以使用。目前可用的硬件距离达到该限制还有 4.5 个数量级。需要非常彻底的硬件重新设计才能接近,当那一天到来时,您将有更大的问题需要担心。在我退休之前,9 EB 的虚拟内存对每个人来说都足够了。

【讨论】:

  • 9 EB 的虚拟内存足够每个人使用,直到我退休:你确定吗?比尔·盖茨曾经对 640 KB 说过同样的话;)(至少传说中是这么说的……)
  • 你读过背景资料吗?我正在编写一个 x64 汇编程序,因此它需要支持 64 位地址。这些地址只是 64 位整数,由 ulong 正确表示。该应用程序与 .Net Framework 地址无关,因此 IntPtr 对我没有用。它旨在生成 x64 二进制文件,而不是某些 .Net 可执行代码。
  • 是什么让您认为汇编器没有与编译器相同的限制?这是一个硬件问题。符合 CLS 的汇编器的概念确实让人喜欢。因此,它需要与不支持无符号整数的 .NET 语言进行交互。他们也不知道如何处理地址。
  • 请这样看:我只是在编写一个库,它必须在特定情况下支持和使用 ulong 数据类型。问题不在于我是否对未来做出了正确的假设。问题是:我将如何为 ulong 属性提供符合 CLR 的替代方案。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    相关资源
    最近更新 更多