2

I have a "JulianDate" struct that I've written in C#, and it has a custom explicit operator to DateTime from the .NET Library. I've used this explicit operator several times in my C# code and it works with no issues.

I now want to use the same explicit operator in my C++/CLI code, but I am unable to figure out how.

I've tried:

  • DateTime^ dt = (DateTime^)jdate; (compiles, but I get an InvalidCastException)
  • DateTime^ dt = safe_cast<DateTime^>(jdate); (I get a compiler error)
  • DateTime^ dt = DateTime(*jdate); (compiles, but dt has wrong data: 1/1/0001 12:00AM)
  • DateTime^ dt = dynamic_cast<DateTime^>(jdate); (compiles, but returns null)

For the safe cast, I'm getting the following error:

`Error  4   error C2682: cannot use 'safe_cast' to convert from 'Solution::Common::JulianDate ^' to 'System::DateTime ^'    C:\Users\9a3eedi\Documents\Solution\Wrapper\Wrapper.cpp 75   Wrapper

What is the proper method of performing an explicit cast? Or is the reason why it's not working is due to me working with structs and not with classes? Or perhaps C++/CLI does not support C# explicit operators?

9a3eedi
  • 696
  • 2
  • 7
  • 18
  • Just to chase the ghosts away I would do a member function which returns what you want and see if that is working. If that works and if you have time to spend on it, you could investigate how to make the cast operator work. – BitTickler Feb 10 '15 at 09:33

1 Answers1

3
   DateTime^ dt = (DateTime^)jdate;

Pretty important in C++/CLI to know when to use the ^ hat. Which is what you are struggling with here, DateTime is a value type and variables of that type should not be declared as references. Just like you'd never write int^ i = 42;. A bit sad that the compiler accepts it anyway, it produces a boxed value. 99.9% of the time that is not what you want, boxing doesn't come for free. You'll dig a much deeper hole when you then try to use it in casts.

Sample C# code:

namespace ClassLibrary45
{
    public struct Julian {
        public static explicit operator Julian(DateTime rhs) {
            return new Julian();
        }
    }
}

Used in sample C++/CLI code:

using namespace System;
using namespace ClassLibrary45;

int main(array<System::String ^> ^args)
{
    DateTime dt = DateTime::Now;
    Julian j = (Julian)dt;
    return 0;
}

Oops, I did it backwards. Well, you get the idea.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Ah so that's what's going on.. I was under the impression that the ^ hat should be used for .NET types, not only reference types. Thank you for the explanation! I got my code to work properly now. – 9a3eedi Feb 10 '15 at 09:57
  • Yes, it should be used for .NET reference types. DateTime is a .NET type. But not a reference type. You'd better get yourself a book to get this down, it is important. – Hans Passant Feb 10 '15 at 10:00
  • I knew that DateTime was a value type and not a reference type. What I didn't know was that ^ basically means that a variable is a reference, and shouldn't be used for value types. – 9a3eedi Feb 10 '15 at 10:05