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

背景

我正在编写一个托管的 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 的上下文中限制库的(某些功能)的使用,只要它可以在大多数情况下使用。

【问题讨论】:

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