1

I'm developing custom Int/UInt classes for larger integers. They work great with assignment/casting/arithmetic, etc. However, it exposed an issue that occurs with xunit and MSTest.

Here's my code:

UInt240 x = 0x7fffffff;
Assert.Equal(0x7fffffff, x);

The issue is that if I supply an unsigned type on the right side, and provide a literal on the left side, it will interpret the literal as an "int" (or relevant signed type that can hold the value), and not be able to cast to the unsigned type (because C# doesn't implicitly cast signed to unsigned types, and xunit is trying to implicitly cast to a common type). MSTest will allow it, interpreting both as "object" objects, but will error because although values match, the types differ.

The same happens with primitives as well normally:

ulong x = 0x7fffffff;
Assert.Equal(0x7fffffff, x);

Is there anything I can do to avoid implicitly casting (ie: "Assert.Equal((ulong)0x7fffffff, x);" )? It would make the code horribly bloated to have to cast types all over the place.

DS7
  • 130
  • 9
  • How does your equals implementation work on your types? is `x.Equals(0)` valid? Would `Assert.True(x.Equals(0));` be an acceptable workaround? Is there a reason you can't explicitly cast 0 to your custom type before doing an Assert.Equals? – Jonathon Chase Sep 19 '18 at 00:22
  • It sounds like defining some assert methods that have overloads for your specific types would be the simplest solution. e.g. `AssertInt.Equal(UInt160, UInt160);` – Mike Zboray Sep 19 '18 at 00:59
  • I updated the question to show the behavior is not something I did, but occurs even with builtin primitives. I would like to alleviate this if possible. @mikez you are correct, but I'd prefer to not go with simple if there's a better option available to me. – DS7 Sep 19 '18 at 01:26

1 Answers1

1

When you declare a literal, you can declare the type, using a suffix. That lets you specify the type of the literal without a cast.

So maybe try this:

UInt240 x = 0x7fffffffUL;
Assert.Equal(0x7fffffffUL, x);
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • I've thought of this, and it's not a bad answer, just kind of annoying to do all the time for signed/unsigned literals. It's essentially just a cleaner way of casting. Kind of what I'm hoping to get away from. It seems like a consequence of how the language is designed, so I can't be too too upset, but I was hoping since I control the class/variable, I can do something to direct behavior in these situations. I'm assuming not though. If not, I'd accept this answer, or extending Assert framework as most sensible. They're both just kind of gross for the end user. – DS7 Sep 19 '18 at 02:31