我正在寻找一种在C#编程语言中使用编译时断言的方法,例如用于C++的BOOST库或新的C++ 0x标准.
我的问题是双重的; 这可以通过标准的便携式C#实现; 或者,可以通过给定C#编译器的怪癖的非可移植假设来实现该行为吗?
谷歌的快速搜索揭示了以下一种技术的链接,其标准符合性和兼容性我不确定.
在具有返回值的函数内,以下技巧/黑客工作(至少在Visual Studio 2005中,未在其他平台上检查过):
Something Foo()
{
if (compiletime_const_condition)
{
// ...
return something;
}
// no return statement at all
}
Run Code Online (Sandbox Code Playgroud)
它不漂亮,但它是我迄今为止最好的解决方案.
该方法与其他没有内置静态断言的语言(Delphi、较旧的 C++ 等)相同:找到一种机制,将要断言的条件转换为编译器不满意的条件(如果条件为假) .
对于 C#,最容易利用的机制之一是关于将负文字/常量分配给无符号类型的警告。这已经在本讨论的某处(或至少在此处链接的页面之一)中被提及,但值得以其纯粹的形式展示。
这是一个保护两个常量的示例 -MODULUS_32并MAX_N防止被编辑为违反预期的值:
const uint _0 = (ulong)MODULUS_32 * MODULUS_32 == MAX_N ? 0 : -666;
Run Code Online (Sandbox Code Playgroud)
这-666使得错误消息可识别为静态断言。在这种情况下使用三元运算符比直接计算更可取,因为这样可以更容易地识别正在发生的事情(计算中的负结果比明确的、故意的分配更有可能归因于错误)。将常量命名为类似的名称_MAX_N_must_be_the_square_of_MODULUS_32会使事情更加明确。
这种类型的“静态断言”可靠地停止编译 - 如果有人篡改/warnaserror开关,这不仅仅是一些可能丢失的警告。
在某些范围内 - 例如,在函数内 - 可能有必要通过编译指示抑制“未使用值”警告:
#pragma warning disable 219
const uint _0 = (ulong)MODULUS_32 * MODULUS_32 == MAX_N ? 0 : -666;
#pragma warning restore 219
Run Code Online (Sandbox Code Playgroud)
C# 与 Delphi 非常相似,因为它缺少预处理器,这意味着静态断言及其机制不能打包成整洁的宏——如果你想使用它们,那么你必须立即输入所有管道。但就像在 Delphi 中一样,让编译器在编译时检查事物的好处是值得的。
Tob*_*ner -1
该代码是标准 C# 代码。它适用于任何编译器 - 但不一定在编译时。由于只有在条件中使用的参数恒定的情况下才可能进行编译时评估,我猜优化取决于编译器供应商/编译器开关。
在 C++ 中,静态断言要么是标准 (C++0x) 的一部分,要么是需要在编译时评估的模板,因此它们可以保证断言。
为了测试可移植性,我会使用不同的编译器,特别是没有任何优化,否则您可能会在程序启动时遇到异常。
| 归档时间: |
|
| 查看次数: |
6903 次 |
| 最近记录: |