Programming dilemma : Need your opinion

37 views
Skip to first unread message

Ruben Willems

unread,
Jun 1, 2014, 2:14:08 PM6/1/14
to ccnet-devel
Hi all

I've got a small programming dilemma with CCNet :-)

The problem is a bit weird : after upgrading CCNet to .Net framework 4.5  one test fails, and I do not know what the problem is.
° is it a breaking change in the .Net framework
° is it a different behavior of Nunit (I upgraded Nunit also to the latest version to be able to test .Net 4.5)
° something else ...

On using the new NUnit on the 1.8.5 tests, all tests are also green.

Below is the test, the bold line is the one that fails, it's one from the dashboard, IO namespace.

        [Test]
        public void NotAvailableNotEvenEqualToItself()
        {
            Assert.AreNotEqual(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
            Assert.AreSame(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
        }

as said before that one works in .Net 3.5, but not in .Net 4.5

I've updated the test to the following and still the same bold line breaks.

        [Test]
        public void NotAvailableNotEvenEqualToItself()
        {
            Assert.IsTrue(ConditionalGetFingerprint.NOT_AVAILABLE == ConditionalGetFingerprint.NOT_AVAILABLE);
            Assert.IsTrue(ConditionalGetFingerprint.Equals(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE));

            Assert.AreNotEqual(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
            Assert.AreSame(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
        }

The same test with the added asserts is still green in .Net 3.5 (with both versions of NUnit)

The code in CCNet uses statements like : (if fingerprint1 == fingerprint2)
as far as I could see, so I would guess that the functionality stays the same, but I'm not 100% sure :-(

I understand the difference between the ==  and the .equals operator
  == tests for object equivalence
  .Equals() test that objects represent the same 'value', they may represent different objects but the value of these are considered the same.


That ConditionalGetFingerprint does an override of the Equals method, so that's why the test is there, and it breaks after upgrading.

And now something really weird :
If I change the test to

        [Test]
        public void NotAvailableNotEvenEqualToItself()
        {
            Assert.AreNotEqual(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
        }


and I change that override equals of the ConditionalGetFingerprint into the following :

        public override bool Equals(object obj)
        {
            Console.WriteLine("Equals method");
            return false;
         }


In .Net framework 3.5 it passes, and I see the string "Equals method" in the output.
In .Net framework 4.5 it does not pass, and I do NOT see the string "Equals method" in the output

?????????????

--> this leads me to the believe that this change in the .Net framework or it's compiler.


and at the bottom it says :

                        In C# 4.0, if the operands to == are "dynamic" then we will do the usual compile-time analysis at runtime based on the runtime types,
                        which effectively does give you something like double-virtual dispatch, at the cost of running the compiler at runtime.
                        We will cache the results of the analysis, so the second time you hit the call site, it should be reasonably efficient.

so does this indeed imply a change in .Net?

I spent some days on finding a solution, but am at rock bottom so far :-(

Any  help, guidance, tips are really appreciated !


with kind regards
Ruben Willems

Leszek Ciesielski

unread,
Jun 4, 2014, 8:44:52 AM6/4/14
to ccnet-devel
Between 3.5 and 4.5 some base framework types added overloaded implementation for the equality operator '==' (e.g. I think Type class had this change), could this be related?


--

---
You received this message because you are subscribed to the Google Groups "ccnet-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ccnet-devel...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ruben Willems

unread,
Jun 4, 2014, 9:46:27 AM6/4/14
to ccnet-devel
That could very be the case.
Do you remember where did you found this information?


with kind regards
Ruben Willems

Matthijs ter Woord

unread,
Jun 4, 2014, 9:52:17 AM6/4/14
to ccnet-devel
You can use reflector to see how == is being executed. ie, if there's some kind of operator implemented, etc..

Leszek Ciesielski

unread,
Jun 4, 2014, 2:44:02 PM6/4/14
to ccnet-devel
I think I was a bit off in my guess - I though I remembered this from Mono class status pages, but there's no commit in Type.cs that would change the behaviour....

Anyway, IMHO this CCNET code should use object.ReferenceEquals instead. Relying on the fact that non-overloaded object.== compares references seems not explicit in the intent - and ReferenceEquals() will produce the same behaviour both on 3.5 and 4.5.

Ruben Willems

unread,
Jul 5, 2014, 1:05:56 AM7/5/14
to ccnet-devel
Hi all

I fixed the error, and the build is green again.

I updated the tests to :

        [Test]
        public void NotAvailableNotEvenEqualToItself()
        {
            Assert.IsFalse(ConditionalGetFingerprint.NOT_AVAILABLE.Equals(ConditionalGetFingerprint.NOT_AVAILABLE));
            Assert.AreSame(ConditionalGetFingerprint.NOT_AVAILABLE, ConditionalGetFingerprint.NOT_AVAILABLE);
        }

I rechecked the code and every call was made via the equals function, and the test above works in .Net 3.5 and 4.5
This test really tests the code that is used.

So probably there was a change somewhere in Nunit with .Net 4.5


Thanks all for the tips !


with kind regards
Ruben Willems

Reply all
Reply to author
Forward
0 new messages