【发布时间】:2010-07-22 11:25:58
【问题描述】:
我想定义一个 Nibble 类型。
我希望如果用户设置的值高于0xf,它应该会产生一个编译器错误。
这可能吗?
【问题讨论】:
-
如果您能指定有问题的编译器,那将非常有帮助。
-
我总是产生编译器错误! :(
标签: .net language-agnostic visual-studio-2010 compiler-errors
我想定义一个 Nibble 类型。
我希望如果用户设置的值高于0xf,它应该会产生一个编译器错误。
这可能吗?
【问题讨论】:
标签: .net language-agnostic visual-studio-2010 compiler-errors
如果您认为USER 是DEVELOPER,您可以使用如下宏来执行此操作:
#if YOUT_VALUE == 0xf
#error YOUR_ERROR_MESSAGE
#endif
但在某些开发环境中,#if 语句中的比较可能会出现问题,因为她的功能仅被剪切为 defied/undefined。
【讨论】:
不,这在 C# 编译器中是不可能的。
它没有像 C/C++ 预处理器那样测试常量值的预处理器。
你能做的最好的事情就是在运行时抛出一个异常。
编辑:您始终可以尝试通过 C/C++ 预处理器运行 C# 代码(稍作改动)并发出 #error 指令。
编辑:
看到这是与语言无关的,是的,您可以在任何支持某种宏扩展或编译时评估的语言中轻松地做到这一点。例如:Scheme、LISP、C/C++ 等。
【讨论】:
您可以使用带有 [Flags] 属性的枚举。这样您就可以对其成员使用按位运算:
[Flags]
enum Nibble
{
_0,
_1,
// ...
_A,
_F,
};
byte b = Nibble._1|Nibble._A;
您还可以使用从 int 到 nibble 的隐式转换运算符创建一个 struct nibble。但这会产生运行时错误,而不是编译时错误。
如果您想进行静态检查,请查看 c#4.0 Contracts API。
【讨论】:
Nibble oops = (Nibble) 255; KABOOM!
看起来实现您想要的最简单的方法是子范围类型。支持子范围类型的语言几乎是 Algol68 继承系列中的所有语言(Algol68、Pascal、Modula-2、Oberon、Component Pascal)及其衍生工具(Turbo Pascal、Borland Pascal、FreePascal、Delphi、Kylix、Object Pascal ) 以及艾达。我相信您可以使用一些繁重的模板来在 C++ 中实现子范围类型。您可能可以使用更具表现力的类型系统的语言来实现它们,例如 Scala、Haskell、ML、Agda、Epigram、Guru。
我不知道为什么没有更多的语言支持子范围类型。它们显然有用、易于使用、易于理解、易于实施。
另一种可能是要塞。在 Fortress 中,各种固定宽度的整数类型实际上并没有内置到语言中,它们是用户定义的。因此,您没有理由不能构建您自己的用户定义的固定宽度整数类型。
【讨论】: