I have a class defined as:
public ref class MyParameters
{
private:
property Decimal^ tickValue;
public:
MyParameters(Decimal^ tickValue){
this->tickValue = tickValue;
}
std::string GetTickValue();
};
std::string MyParameters::GetTickValue()
{
String^ test = this->tickValue->ToString(); <--Invalid Cast here
return marshal_as<std::string>(test);
}
If I breakpoint on that line and paste this->tickValue->ToString() into the quick watch it works fine!
I did notice that my Constructor signature was changed to MyParameters(ValueType^ tickValue)??
The is no concept of “typed reference to value type” in .Net.* And since
Decimal^is exactly that, it’s not possible to compile that properly. As you noticed, what the compiler does is to instead make the parameterValueType^, which is the closest thing toDecimal^in the .Net type system. It also adds some metadata, so that when you call the constructor from C++/CLI, only boxedDecimalcan be passed to it.But other languages don’t understand that metadata, all they see is
ValueType. That means that you can call the constructor from, say, C# like this and it works fine:Notice that I passed in an
int, notdecimal. And thisintis saved in thetickValuefield (which is actually alsoValueType^). And only when trying to actually use its value asDecimal^, you getInvalidCastException.The easiest way to fix this is not to use references to value types. That is, instead of
Decimal^, use justDecimaland everything should work fine.* Strictly speaking, there is
TypedReference, but that’s not meant for normal use.