如何在C#中声明一个编译时常量函数

8
在C++中,我们可以使用宏或constexpr(如C++11所述)。在C#中我们该怎么做?
请参见上下文中的“无法声明…”注释:
static class Constant
{
    // we must ensure this is compile time const, have to calculate it from ground...
    public const int SIZEOF_TEXUTRE_RGBA_U8C4_640x480 = 4 * sizeof(byte) * 640 * 480;

    // Cannot declare compile time constant as following in C#
    //public const int SIZEOF_TEXUTRE_RGBA_U8C4_640x480_2 = 4 * PixelType._8UC4.PixelSize() * 640 * 480;
}

public static class PixelTypeMethods
{
    public static /*constexpr*/ int PixelSize(this PixelType type)
    {
        int value = (int)type;
        int unit_size = value & 0xFF;
        int unit_count = (value & 0xFF00) >> 8;
        return unit_count * unit_size;
    }
}

[Flags]
public enum PixelType
{
    RGBA_8UC4 = RGBA | _8U | _C4,

    /////////////////////////
    RGBA = 1 << 16,

    /////////////////////////
    _8UC4 = _8U | _C4,

    /////////////////////////
    _C4 = 4  << 8,

    /////////////////////////
    _8U = sizeof(byte)
}

这是在问C#是否有类似于C++11中的constexpr的等效物吗? - onezeno
1个回答

6

要声明一个常量(const),被赋值的值必须是编译时常量。调用方法会自动使其不是编译时常量。

另一种选择是使用 static readonly

public static readonly int SIZEOF_TEXUTRE_RGBA_U8C4_640x480_2 =
    4 * PixelType._8UC4.PixelSize() * 640 * 480;

我必须将 SIZEOF_TEXUTRE_RGBA_U8C4_640x480_2 声明为 'const',因为未来的代码需要编译时常量…… 'readonly' 广播运行时依赖于……这是 C# 语言的限制吗?无法声明编译时 const 函数?是否有任何解决方法? - Raymond
@Raymond:未来代码为什么需要编译时常量? - Daniel Hilgarth
1
@Raymond: 我有一种感觉,你并不真正理解 编译时常量 的含义。它意味着该值已知于编译器。此外,这也意味着常量声明将完全从生成的 IL 代码中消失,因为常量的值被内联到其使用的任何地方。C# 编译器不会执行当前正在编译的程序代码,因此不可能将方法声明为编译时常量。 - Daniel Hilgarth
1
我清除了编译时间,但我确实想简化我的示例代码中的“const”声明。SIZEOF_TEXUTRE_RGBA_U8C4_640x480_2只是从其他const计算出来的一个简单的const。这个“计算公式”很简单。我想要“重用”这个公式。 - Raymond
4
@Raymond:你做不到。C#中没有预处理器,也没有支持模板元编程的实际方法。 - Daniel Hilgarth
另一个思考方式是:静态构造函数可以执行任意的static代码(且public static readonly int x = 20只是静态构造函数的一种语法糖替代——静态构造函数在运行时被调用,而非编译时),但编译器不能运行代码,因为C#编译器没有像C语言族那样的预处理器。 - jrh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接