【问题标题】:Optional parameters “must be a compile-time constant”可选参数“必须是编译时常量”
【发布时间】:2013-08-22 13:27:19
【问题描述】:

我遇到了与this SO question 中描述的问题类似的问题 然而,在我的情况下,可选参数默认值为:
1. 在单独的 C++/CLI dll 中定义。
2. 已在该库中定义为“public static const”
当我尝试将该值用作 C# 中的默认参数值时,我得到“必须是编译时间常数”。
有没有办法在 (C++/cli) 库和 (C#) 应用程序之间共享一个共同的 const 值?

C++/CLI 库:

namespace MyCPlusPlusCLILib {
    public ref class CPPCLIClass {
    public:
       static const double Invalid = -1;
}

C#代码:

public MyMethod(double fish = MyCPlusPlusCLILib.CPPCLIClass.Invalid) { }
// C# compiler error "Must be a compile time const"

const double MyConstDouble = MyCPlusPlusCLILib.CPPCLIClass.Invalid;
// C# compiler error "Must be a compile time const"

【问题讨论】:

  • 参数是什么类型的?
  • 请贴一些代码。
  • 我想应该是const 而不是static const
  • @close voter:请澄清您的接近投票。
  • @SriramSakthivel:在 C# 中 const => static - 这是 C++ 的情况吗?我不这么认为。即在 C# 中 const 可以作为静态访问,但在 C++ 中并非如此,所以我认为它确实需要在那里是静态的。

标签: c# c++-cli constants default-value


【解决方案1】:

C++ 中的 const 关键字声明的常量并非都是 const,它可以通过 const_cast 任意丢弃。

您需要使用特定于 C++/CLI 的关键字来声明 .NET 常量,该常量的值存储在元数据中,但也没有底层存储。使用 literal 关键字:

    literal double Invalid = -1;

这解决了您的问题,C# 编译器对此很满意。请注意公共常量的不确定性。您的 C# 编译器会将值直接编译到生成的 IL 中,用文字值替换“无效”。当您使用更改文字但不重新编译 C# 代码的错误修复来更新 C++/CLI 程序集时,结果会很糟糕。公共常量适用于清单常量,例如 Math::Pi。

【讨论】:

  • const,只读,字面量... 被宠坏了。这确实是我一直在寻找的解决方案。在这种情况下,Ifiness 被理解和接受(C++ 代码是固件代码的构建 - 不会急于改变)。谢谢。
  • 不,您不能使用const_cast 从声明为const 的对象中删除const。 C# const 更类似于 C++ constexpr。 C++ const,用于对象(不是指针或引用的目标类型)意味着初始化后值不能更改,但是可以从运行时变量计算初始(和永久)值。 C++ const(同样,在对象上,而不是句柄的目标类型上)对应于不变性。
【解决方案2】:

MyCPlusPlusCLILib.CPPCLIClass.Invalid 不是编译时常量,因为您可以输入不同版本的MyCPlusPlusCLILib,并将Invalid 设置为不同的值。

如果您不想将 C# 方法的默认值设为显式 -1,您可以执行以下操作:为 C# 默认值选择一个不同的值,当您得到该值时,在 C++ 中替换/CLI Invalid.

public void MyMethod(double fish = Double.NaN)
{
    if (Double.IsNaN(fish))
        fish = MyCPlusPlusCLILib.CPPCLIClass.Invalid;

    ...
}

【讨论】:

  • 那么有什么解决办法。我想在 C++/Cli 和 C# 代码之间共享一个无效值 - 这可能吗?
  • 查看编辑。无法直接共享该值,但您可以使用一个默认值来触发另一个默认值的使用。
  • 这是一个解决方案 +1 - 我认为我认为它不会受到 Hans 解决方案的影响是正确的 - 因为如果更新 lib,旧的清晰代码仍会从 lib 中提取新的 lib 值。但在这种特殊情况下,我可以忍受 ifiness 和文字更干净。谢谢。
猜你喜欢
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2022-07-07
  • 2014-07-31
  • 1970-01-01
  • 2018-11-13
相关资源
最近更新 更多