Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert.AreEqual fails for int and ulong but not long and uint

Tags:

c#

.net

Well, I hope my processor is not burned, because:

    [TestMethod]
    public void tenEqualten()
    {
        Int64 a = 10;
        UInt32 b = 10;
        Assert.AreEqual(a, b);
    }

works just fine, but this:

    [TestMethod]
    public void tenNotEqualten()
    {
        Int32 a = 10;
        UInt64 b = 10;
        Assert.AreEqual(a, b);
    }

fails miserably.

Have you got same results, or is it just me? If yes, any ideas, why? If this is known issue for .Net 4.5 than sorry for spam, but I could not find that as a bug.

edit: I found a duplicate here and an explanation here

like image 356
Piotr Falkowski Avatar asked Nov 11 '14 22:11

Piotr Falkowski


3 Answers

In the first method you are calling Assert.AreEqual<T>(T expected, T actual) where T is of type Int64, this is because UInt32 is implicitly castable to Int64. It is the same effect as if you did

    [TestMethod]
    public void tenEqualten()
    {
        Int64 a = 10;
        UInt32 b = 10;
        Assert.AreEqual(a, (Int64)b);
    }

That is why the first version passes.

In the second version you are calling Assert.AreEqual(object expected, object actual) which fails because they are different types and therefor not "equal".

You could make your first version act like your second version by putting the two numbers inside a object this would let you use the same overload of Assert.

    [TestMethod]
    public void tenEqualten()
    {
        Int64 a = 10;
        UInt32 b = 10;
        object c = a;
        object d = b;
        Assert.AreEqual(c, d);
    }

This method will fail exactly the same way your tenNotEqualten method will fail.

like image 177
Scott Chamberlain Avatar answered Nov 18 '22 16:11

Scott Chamberlain


Look at the widening table.

Integer -> Integer , Long, Decimal, Single, Double
UInteger -> UInteger , Long, ULong, Decimal, Single, Double

How does this relate to your code?

When you compare long (Int64) with uint (UInt32), the uint can fit a long so there's no problem here.

However when you compare int (Int32) with ulong (UInt64) you can see that there is no implicit widening available: they don't fit in eachother.

You can see this more clearly by just looking at the method resolution done by intellisense:

enter image description here

enter image description here

And finally:

object c = (int) 10;
object d = (ulong) 10;
Console.WriteLine (c == d);

will yield false

like image 41
Jeroen Vannevel Avatar answered Nov 18 '22 16:11

Jeroen Vannevel


UInt32 can be cast to Int64 but UInt64 can not be cast to Int32 as it would not fit. You would get a compilation error on the c == d check in the example below.

Int64 a = 10;
UInt32 b = 10;

Console.WriteLine(a == b);

Int32 c = 10;
UInt64 d = 10;

Console.WriteLine(c == d);
like image 7
Magnus Avatar answered Nov 18 '22 17:11

Magnus