I have a similar problem the issue described in this SO question
In my case however the optional param default values is:
1. Defined in a separate C++/CLI dll.
2. Is already defined in that lib as "public static const"
When I try to use the value as a default parameter value from C# I get "must be a compile time constant".
Is there a way to share a common const value between (C++/cli) library and (C#) app?
C++/CLI lib:
namespace MyCPlusPlusCLILib {
public ref class CPPCLIClass {
public:
static const double Invalid = -1;
}
C# code:
public MyMethod(double fish = MyCPlusPlusCLILib.CPPCLIClass.Invalid) { }
// C# compiler error "Must be a compile time const"
OR
const double MyConstDouble = MyCPlusPlusCLILib.CPPCLIClass.Invalid;
// C# compiler error "Must be a compile time const"
The const keyword in C++ declares constants that are not all that const, it can be arbitrarily cast away with a const_cast<>.
You'll need to use a C++/CLI specific keyword to declare a .NET constant, the kind whose value is stored in the metadata but doesn't also have underlying storage. Use the literal keyword:
literal double Invalid = -1;
Which solves your problem, the C# compiler is happy with that one. Do note the iffiness of public constants. Your C# compiler will compile the value into the generated IL directly, substituting "Invalid" with the literal value. This will turn out poorly when you update your C++/CLI assembly with a bug fix that changes the literal but don't recompile the C# code. Public constants are okay for manifest constants, like Math::Pi.
MyCPlusPlusCLILib.CPPCLIClass.Invalid is not a compile-time constant, because you could put in a different version of MyCPlusPlusCLILib, with Invalid set to a different value.
If you don't want to make the default value for the C# method an explicit -1, you could do something like this: Pick a different value for a C# default, and when you get that, substitute in the C++/CLI Invalid.
public void MyMethod(double fish = Double.NaN)
{
if (Double.IsNaN(fish))
fish = MyCPlusPlusCLILib.CPPCLIClass.Invalid;
...
}
The const keyword in C++ declares constants that are not all that const, it can be arbitrarily cast away with a const_cast<>.
You'll need to use a C++/CLI specific keyword to declare a .NET constant, the kind whose value is stored in the metadata but doesn't also have underlying storage. Use the literal keyword:
literal double Invalid = -1;
Which solves your problem, the C# compiler is happy with that one. Do note the iffiness of public constants. Your C# compiler will compile the value into the generated IL directly, substituting "Invalid" with the literal value. This will turn out poorly when you update your C++/CLI assembly with a bug fix that changes the literal but don't recompile the C# code. Public constants are okay for manifest constants, like Math::Pi.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With