Exemple #1
0
        public void TestAdaptation()
        {
            AdaptationTestBase t = GoInterface <AdaptationTestBase, AdaptationTests1> .ForceFrom(new AdaptationTests1());

            t.Passthrough(1, 2, 3, "4");
            int i; double d; object o; string s;

            Assert.That(t.Passthrough(out i, out d, out o, out s));
            Assert.AreEqual(i, 1);
            Assert.AreEqual(d, 2);
            Assert.AreEqual(o, 3);
            Assert.AreEqual(s, "4");
            Assert.That(t.Enlarge2int((short)-1, true));
            Assert.That(t.Enlarge2int((ushort)0xFFFF, false));
            Assert.That(t.Enlarge2uint((byte)0xFF));
            Assert.That(t.Enlarge2uint((ushort)0xFFFF));
            Assert.That(t.Enlarge2long(-1, true));
            Assert.That(t.Enlarge2long((ushort)0xFFFF, false));
            Assert.That(t.Enlarge2long((uint)0xFFFFFFFF, false));
            Assert.That(t.Enlarge2float(1));
            Assert.That(t.Enlarge2double(1));
            Assert.That(t.Box((int)1));
            Assert.That(t.Box(1.0));
            Assert.That(t.Renamed());

            t = GoInterface <AdaptationTestBase, AdaptationTests2> .ForceFrom(new AdaptationTests2());

            t.Covariant(out i);
            Assert.That(i == 1);
            IDisposable idisp;

            t.Covariant(out idisp);
            Assert.That(idisp is MemoryStream);
            i = 0;
            Assert.That(t.Covariant2(ref i));
            Assert.AreEqual(1, i);
            s = "1";
            Assert.That(t.Invariant(ref s));
            Assert.That(t.Invariant2(s));
            Assert.That(t.Contravariant("1"));
            Assert.That(t.Contravariant(new MemoryStream()));
            Assert.That(t.Contravariant2(1));
            i = 1;
            Assert.That(t.Contravariant3(ref i));
            t.CovariantReturn();
            Assert.That(t.CovariantReturn2() is bool);
            Assert.That(t.CovariantReturn3().ToString() == "true");
            Assert.AreEqual(t.CovariantReturn4(), 1.0f);
            Assert.That(t.DroppedParam(1));
            Assert.That(t.DroppedParam2());
            Assert.That(t.DroppedParam3("1"));
            Assert.That(t.DefaultParam());
        }
Exemple #2
0
        public void InheritanceTest()
        {
            object  something = new FooB();
            FooBase foo       = GoInterface <FooBase> .From(something);

            Assert.That(foo.Foo() == "Foo");
            Assert.That(foo.Bar() == "Bar");
            Assert.That(foo.Baz(1) == "Baz");
            Assert.That(((IBaz)foo).Baz(false) == "Baz");
            Assert.That(foo.Baz() == "Baz");

            something = new FooB();
            IBaz baz = GoInterface <IBaz> .ForceFrom(something);

            Assert.That(((IBar)baz).Bar() == "Bar");
            Assert.That(((IBar2)baz).Bar() == "Bar");
            Assert.That(baz.Baz() == "Baz");
        }
Exemple #3
0
        public void TestOverloading()
        {
            bool             correct;
            int              x = 1;
            object           o;
            IOverloadingTest i = GoInterface <IOverloadingTest> .ForceFrom(new OverloadingTest());

            Assert.That(i.MoreMatchingArgsAreBetter(1, 2));
            Assert.That(i.MoreMatchingArgsAreBetter2(1, 2, 3));
            Assert.That(i.MinimumSizeRequired(1));
            Assert.That(i.MinimumSizeRequired2(1));
            Assert.That(i.SignedIsBetter(1));
            Assert.That(i.SignedIsBetter2(1));
            Assert.That(i.UnsignedIsBetter(1));
            Assert.That(i.UnsignedIsBetter2(1));
            Assert.That(i.IntIsBetter(1));
            Assert.That(i.FloatIsBetter(1));
            Assert.That(i.FloatIsBetter2(1.0f));
            Assert.That(i.MissingOutput(1));
            Assert.That(i.MissingOutput2());
            Assert.That(i.MissingInput(1, 2, 3));
            Assert.That(i.MissingInput2(1, 2));
            Assert.That(i.MissingInputAndOutput(1, 2, 3));
            Assert.That(i.OptionalParam(1, 2));
            Assert.That(i.OptionalParam2(1, 2, 3));
            Assert.That(i.RefMismatch(1));
            Assert.That(i.RefMismatch2(1));
            Assert.That(i.RefMismatch3(ref x));
            Assert.That(i.RefMismatch4(ref x));
            Assert.That(i.RefMismatch5(1));
            Assert.That(i.Contravariance("1"));
            Assert.That(i.Contravariance2(new MemoryStream()));
            Assert.That(i.Contravariance3(new MemoryStream()));
            Assert.That(i.Covariance(out x));
            Assert.That(i.Covariance2(out o));
            Assert.That(i.ReturnCovariance() is int && (int)i.ReturnCovariance() == 1);
            Assert.That(i.ReturnCovariance2() == 1.0f);
            i.ReturnCovariance3(out correct);
            Assert.That(correct);
            Assert.That(i.ChooseTheMatchingReturn(1));
            Assert.That(i.IgnoreNonPublic(1));
        }
Exemple #4
0
        public void TestAmbiguity()
        {
            IAmbig wrapped;

            try {
                wrapped = GoInterface <IAmbig> .From(new Ambig());
            }
            catch (InvalidCastException e)
            {
                if (e.Message.Contains("4 "))
                {
                    return;                     // 4 ambiguous methods, just as expected
                }
            }

            wrapped = GoInterface <IAmbig> .ForceFrom(new Ambig());

            int a = 0;

            Assert.ThrowsAny <MissingMethodException>(delegate() { wrapped.Strings("1", "2"); });
            Assert.ThrowsAny <MissingMethodException>(delegate() { wrapped.RefMismatch(1, 2); });
            Assert.ThrowsAny <MissingMethodException>(delegate() { wrapped.RefMismatch2(ref a, 2); });
            Assert.ThrowsAny <MissingMethodException>(delegate() { wrapped.AmbigLarger(1); });
        }
        public static void DoBenchmark()
        {
            const int Iterations = 100000000;

            // Measure the time it takes to instantiate ten versions of
            // IReadOnlyList<T>. GoInterface is not able to create generic wrappers,
            // so every time you wrap the same generic type with a different type
            // parameter, GoInterface produces a completely separate wrapper. This
            // is not good for performance, but at least it makes it easy for our
            // benchmark to pick 10 "different" classes to create wrappers of.
            //
            // It is possible to wrap List<byte> not only as IReadOnlyList<byte>
            // but also as any larger integer type, such as IReadOnlyList<int>.
            // However, the wrapping of the GetEnumerator() methods doesn't work.
            // List<byte>.GetEnumerator() returns IEnumerator<byte>, but
            // IReadOnlyList<int>.GetEnumerator() returns IEnumerator<int>. There is
            // no implicit conversion from IEnumerator<byte> to IEnumerator<int>,
            // so GoInterface fails to wrap it. However, by using ForceFrom we get
            // around this limitation, which still allows us to use the indexer and
            // Count properties. If you call GetEnumerator(), though, you get a
            // MissingMethodException.
            //
            // Note that if you run this part of the benchmark twice without
            // exiting the program, the second time around it should take zero
            // milliseconds. And the benchmark generally runs more slowly right
            // after you reboot your computer.
            SimpleTimer timer  = new SimpleTimer();
            var         dummy0 = GoInterface <IReadOnlyList <byte> > .ForceFrom(new List <byte>());

            int firstOne = timer.Restart();
            var dummy1   = GoInterface <IReadOnlyList <short> > .ForceFrom(new List <byte>());

            var dummy2 = GoInterface <IReadOnlyList <ushort> > .ForceFrom(new List <byte>());

            var dummy3 = GoInterface <IReadOnlyList <int> > .ForceFrom(new List <byte>());

            var dummy4 = GoInterface <IReadOnlyList <uint> > .ForceFrom(new List <byte>());

            var dummy5 = GoInterface <IReadOnlyList <long> > .ForceFrom(new List <byte>());

            var dummy6 = GoInterface <IReadOnlyList <ulong> > .ForceFrom(new List <byte>());

            var dummy7 = GoInterface <IReadOnlyList <float> > .ForceFrom(new List <byte>());

            var dummy8 = GoInterface <IReadOnlyList <double> > .ForceFrom(new List <byte>());

            var dummy9 = GoInterface <IReadOnlyList <object> > .ForceFrom(new List <byte>());

            int nineMore = timer.Millisec;

            Console.WriteLine("First interface wrapped in {0}ms; nine more took {1}ms", firstOne, nineMore);

            // Second test: measure how long it takes to wrap the same List<int>
            // many times, using either GoInterface class.
            var list = new List <int>();

            list.Add(0);
            list.Add(1);
            list.Add(2);
            list.Add(3);
            IList <int>         ilist;
            IReadOnlyList <int> rolist;

            GoInterface <IReadOnlyList <int> > .From(list);         // ignore first call

            timer.Restart();
            int i = 0;

            do
            {
                ilist = list;                 // normal interface assignment is pretty much a no-op
            } while (++i < Iterations);
            int wrapTest0 = timer.Restart();

            i = 0;
            do
            {
                rolist = GoInterface <IReadOnlyList <int> > .From(list);
            } while (++i < Iterations);
            int wrapTest1 = timer.Restart();

            i = 0;
            do
            {
                rolist = GoInterface <IReadOnlyList <int>, List <int> > .From(list);
            } while (++i < Iterations);
            int wrapTest2 = timer.Restart();

            Console.WriteLine("Wrapper creation speed ({0} million times):", Iterations / 1000000);
            Console.WriteLine("- {0} ms for normal .NET interfaces (no-op)", wrapTest0);
            Console.WriteLine("- {0} ms for GoInterface<IReadOnlyList<int>>.From()", wrapTest1);
            Console.WriteLine("- {0} ms for GoInterface<IReadOnlyList<int>,List<int>>.From()", wrapTest2);

            int total0 = 0, total1 = 0, total2 = 0;

            timer.Restart();
            for (i = 0; i < Iterations; i++)
            {
                total0 += list[i & 3];
            }
            int callTestDirectCall = timer.Restart();

            for (i = 0; i < Iterations; i++)
            {
                total1 += ilist[i & 3];
            }
            int callTestNormalInterface = timer.Restart();

            for (i = 0; i < Iterations; i++)
            {
                total2 += rolist[i & 3];
            }
            int callTestGoInterface = timer.Restart();

            Debug.Assert(total0 == total1 && total1 == total2);

            Console.WriteLine("Time to call indexer of List<int> ({0} million times):", Iterations / 1000000);
            Console.WriteLine("- {0} ms for direct calls (not through an interface)", callTestDirectCall);
            Console.WriteLine("- {0} ms through IList<int> (normal interface)", callTestNormalInterface);
            Console.WriteLine("- {0} ms through IReadOnlyList<int> (GoInterface)", callTestGoInterface);
        }