public void ExtendedType_SearchWithCast()
        {
            ExtendedType et  = typeof(ComplexOverloads <int>);
            Method       add = et.GetMethod("Add", typeof(short), typeof(short), typeof(int));

            Assert.IsNotNull(add);
        }
        public void ExtendedType_GetMethod_CreatesConcreteMethods()
        {
            // Get the open type.
            ExtendedType openType = ExtendedType.Get(typeof(ComplexOverloads <>));

            Assert.IsTrue(openType.Type.ContainsGenericParameters);

            // Note this not only creates a concrete method by setting the method type param to Guid
            // It also has to make the enclosing type concrete by changing it to ComplexOverloads<bool> as
            // the first parameter uses the type's generic parameter.
            //
            // It actually matches: public void A<T1>(T a, ref T1 b) {}
            Method concreteMethod = openType.GetMethod(
                "A",
                1,
                typeof(bool),
                typeof(Guid).MakeByRefType(),
                TypeSearch.Void);

            Assert.IsNotNull(concreteMethod);
            Assert.IsFalse(concreteMethod.Info.ContainsGenericParameters);
            Assert.IsFalse(concreteMethod.ExtendedType.Type.ContainsGenericParameters);
            // The GetMethod
            Assert.AreNotSame(openType, concreteMethod.ExtendedType);
        }
        public void ExtendedType_CanGetConcreteMethods()
        {
            // Get the open type.
            ExtendedType openType = ExtendedType.Get(typeof(ComplexOverloads <>));

            Assert.IsTrue(openType.Type.ContainsGenericParameters);

            // Close the type
            ExtendedType closedType = openType.CloseType(typeof(int));

            Assert.IsNotNull(closedType);
            Assert.IsFalse(closedType.Type.ContainsGenericParameters);
            Assert.AreSame(openType.Type, closedType.Type.GetGenericTypeDefinition());

            // This time we have a concrete type.
            Method method = closedType.GetMethod("A", typeof(int));

            Assert.IsNotNull(method);
            // This method has no generic arguments and the type is concrete.
            Assert.IsFalse(method.Info.ContainsGenericParameters);

            Method method2 = closedType.GetMethod("A", 1, typeof(string), TypeSearch.Void);

            Assert.IsNotNull(method2);
            // This method has generic arguments and so it does contain generic parameters even though type is concrete.
            Assert.IsTrue(method2.Info.ContainsGenericParameters);

            // We can use the CloseMethod overload to close the method.
            Method method3 = method2.Close(typeof(int));

            Assert.IsNotNull(method3);
            // We haven't closed the extended type.
            Assert.AreSame(method2.ExtendedType, method3.ExtendedType);
            Assert.IsFalse(method3.ExtendedType.Type.ContainsGenericParameters);
            Assert.IsFalse(method3.Info.ContainsGenericParameters);

            // Finally we get the open type's open method.
            Method method4 = openType.GetMethod("A", 1, typeof(string), TypeSearch.Void);

            Assert.IsNotNull(method4);
            Assert.IsTrue(method4.Info.ContainsGenericParameters);
        }
        public void Method_ParameterlessStaticFuncValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("StaticGetOne", typeof(int));

            Assert.IsNotNull(method);
            Func <int> getOne = method.GetFunc(typeof(int)) as Func <int>;

            Assert.IsNotNull(getOne);
            Assert.AreEqual(1, getOne());
        }
        public void Method_StaticFuncValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("StaticAdd", typeof(int), typeof(int), typeof(int));

            Assert.IsNotNull(method);
            Func <int, int, int> add = method.GetFunc(typeof(int), typeof(int), typeof(int)) as Func <int, int, int>;

            Assert.IsNotNull(add);
            int a = Random.Next();
            int b = Random.Next();

            Assert.AreEqual(a + b, add(a, b));
        }
        public void Method_ParameterlessStaticActionValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("StaticIncrementCounter", typeof(void));

            Assert.IsNotNull(method);
            Action increment = method.GetAction() as Action;

            Assert.IsNotNull(increment);

            int original = ComplexOverloads <int> .StaticCounter;

            increment();
            Assert.AreEqual(original + 1, ComplexOverloads <int> .StaticCounter);
        }
        public void Method_StaticActionValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("StaticIncrementCounter", typeof(int), typeof(void));

            Assert.IsNotNull(method);
            Action <int> increment = method.GetAction(typeof(int)) as Action <int>;

            Assert.IsNotNull(increment);

            int a        = Random.Next();
            int original = ComplexOverloads <int> .StaticCounter;

            increment(a);
            Assert.AreEqual(original + a, ComplexOverloads <int> .StaticCounter);
        }
        public void Method_ParameterlessInstanceFuncValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("GetOne", typeof(int));

            Assert.IsNotNull(method);
            Func <ComplexOverloads <int>, int> getOne = method.GetFunc(
                typeof(ComplexOverloads <int>),
                typeof(int)) as Func <ComplexOverloads <int>, int>;

            Assert.IsNotNull(getOne);

            ComplexOverloads <int> obj = new ComplexOverloads <int>();

            Assert.AreEqual(1, getOne(obj));
        }
        public void Method_ParameterlessInstanceActionValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("IncrementCounter", typeof(int));

            Assert.IsNotNull(method);
            Action <ComplexOverloads <int> > increment = method.GetAction(
                typeof(ComplexOverloads <int>)) as Action <ComplexOverloads <int> >;

            Assert.IsNotNull(increment);

            ComplexOverloads <int> obj = new ComplexOverloads <int>();
            int original = obj.Counter;

            increment(obj);
            Assert.AreEqual(original + 1, obj.Counter);
        }
        public void Method_InstanceActionValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("IncrementCounter", typeof(int), typeof(void));

            Assert.IsNotNull(method);
            Action <ComplexOverloads <int>, int> increment =
                method.GetAction(typeof(ComplexOverloads <int>), typeof(int)) as Action <ComplexOverloads <int>, int>;

            Assert.IsNotNull(increment);

            ComplexOverloads <int> obj = new ComplexOverloads <int>();
            int original = obj.Counter;
            int a        = Random.Next();

            increment(obj, a);
            Assert.AreEqual(original + a, obj.Counter);
        }
        public void Method_InstanceFuncValid()
        {
            ExtendedType et     = typeof(ComplexOverloads <int>);
            Method       method = et.GetMethod("Add", typeof(int), typeof(int), typeof(int));

            Assert.IsNotNull(method);
            Func <ComplexOverloads <int>, int, int, int> add = method.GetFunc(
                typeof(ComplexOverloads <int>),
                typeof(int),
                typeof(int),
                typeof(int)) as
                                                               Func <ComplexOverloads <int>, int, int, int>;

            Assert.IsNotNull(add);
            int a = Random.Next();
            int b = Random.Next();

            ComplexOverloads <int> obj = new ComplexOverloads <int>();

            Assert.AreEqual(a + b, add(obj, a, b));
        }
Beispiel #12
0
        public Method Close([NotNull] Type[] typeClosures, [NotNull] Type[] signatureClosures)
        {
            if (typeClosures == null)
            {
                throw new ArgumentNullException("typeClosures");
            }
            if (signatureClosures == null)
            {
                throw new ArgumentNullException("signatureClosures");
            }

            Debug.Assert(_genericArguments.Value != null);

            // Check input arrays are valid.
            if ((typeClosures.Length != ExtendedType.GenericArguments.Count()) ||
                (signatureClosures.Length != _genericArguments.Value.Count()))
            {
                return(null);
            }

            // If we have any type closures then we need to close the type and look for the method on there.
            if (typeClosures.Any(t => t != null))
            {
                // Close type
                ExtendedType et = ExtendedType.CloseType(typeClosures);

                // Check closure succeeded.
                if (et == null)
                {
                    return(null);
                }

                // Create new search.
                Debug.Assert(_parameters.Value != null);
                int          pCount               = _parameters.Value.Length;
                TypeSearch[] searchTypes          = new TypeSearch[pCount + 1];
                Type[]       typeGenericArguments = et.GenericArguments.Select(g => g.Type).ToArray();
                // Search for closed
                for (int i = 0; i < pCount; i++)
                {
                    Debug.Assert(_parameters.Value[i] != null);
                    Type pType = _parameters.Value[i].ParameterType;
                    Debug.Assert(pType != null);
                    searchTypes[i] = Reflection.ExpandParameterType(pType, signatureClosures, typeGenericArguments);
                }

                // Add return type
                Type rType = Info.ReturnType;
                searchTypes[pCount] = Reflection.ExpandParameterType(rType, signatureClosures, typeGenericArguments);

                // Search for method on new type.
                return(et.GetMethod(Info.Name, signatureClosures.Length, searchTypes));
            }

            // Substitute missing types with concrete ones.
            int closures = signatureClosures.Length;

            Type[] gta = new Type[closures];
            for (int i = 0; i < closures; i++)
            {
                gta[i] = signatureClosures[i] ?? _genericArguments.Value[i].Type;
            }

            // Create closed method, cache it and return.
            // ReSharper disable once AssignNullToNotNullAttribute
            string key = string.Join("|", gta.Select(t => ExtendedType.Get(t).Signature));

            Debug.Assert(_closedMethods.Value != null);
            return(_closedMethods.Value.GetOrAdd(
                       key,
                       k =>
            {
                try
                {
                    return new Method(ExtendedType, Info.MakeGenericMethod(gta));
                }
                catch (ArgumentException)
                {
                    return null;
                }
            }));
        }
        public void ExtendedType_CanDisambiguateMembers()
        {
            ExtendedType et = ExtendedType.Get(typeof(ComplexOverloads <>));

            IEnumerable <Method> methods = et.GetMethods("A");

            Assert.IsNotNull(methods);
            Assert.AreEqual(8, methods.Count()); //Assert.AreEqual(9, methods.Count());

            Method invalidMethod = et.GetMethod("A");

            Assert.IsNull(invalidMethod);

            Method method1 = et.GetMethod("A", TypeSearch.T1);

            Assert.IsNotNull(method1);
            Assert.IsTrue(method1.Info.ContainsGenericParameters);

            // Demonstrate cast to void
            bool[] castsRequired;
            invalidMethod = et.GetMethod("A", 0, true, true, out castsRequired, TypeSearch.Void);
            Assert.IsNotNull(invalidMethod);
            Assert.IsTrue(castsRequired[0]);

            Method method2 = et.GetMethod("A", typeof(int), TypeSearch.Void);

            Assert.IsNotNull(method2);
            Assert.AreNotEqual(method1, method2);

            Method method3 = et.GetMethod("A", typeof(int).MakeByRefType(), TypeSearch.Void);

            Assert.IsNotNull(method3);
            Assert.AreNotEqual(method3, method1);
            Assert.AreNotEqual(method3, method2);

            /*
             * Method method3b = et.GetMethod("A", typeof (int).MakePointerType(), TypeSearch.Void);
             * Assert.IsNotNull(method3b);
             * Assert.AreNotEqual(method3b, method1);
             * Assert.AreNotEqual(method3b, method2);*/

            Method method4 = et.GetMethod("A", typeof(string), typeof(string), TypeSearch.Void);

            Assert.IsNotNull(method4);
            Assert.IsTrue(method4.Info.IsStatic);
            Assert.AreNotEqual(method4, method1);
            Assert.AreNotEqual(method4, method2);
            Assert.AreNotEqual(method4, method3);

            Method method5 = et.GetMethod("A", typeof(string), typeof(string).MakeByRefType(), TypeSearch.Void);

            Assert.IsNotNull(method5);
            Assert.AreNotEqual(method5, method1);
            Assert.AreNotEqual(method5, method2);
            //Assert.AreNotEqual(method5, method3b);
            Assert.AreNotEqual(method5, method4);

            Method method6 = et.GetMethod("A", 1, typeof(string), TypeSearch.Void);

            Assert.IsNotNull(method6);
            Assert.AreNotEqual(method6, method1);
            Assert.AreNotEqual(method6, method2);
            //Assert.AreNotEqual(method6, method3b);
            Assert.AreNotEqual(method6, method4);
            Assert.AreNotEqual(method6, method5);

            Method method7 = et.GetMethod("A", 2, typeof(string), TypeSearch.Void);

            Assert.IsNotNull(method7);
            Assert.AreNotEqual(method7, method1);
            Assert.AreNotEqual(method7, method2);
            //Assert.AreNotEqual(method7, method3b);
            Assert.AreNotEqual(method7, method4);
            Assert.AreNotEqual(method7, method5);
            Assert.AreNotEqual(method7, method6);

            Method method8 = et.GetMethod(
                "A",
                1,
                new TypeSearch(GenericArgumentLocation.Type, "T"),
                new TypeSearch(GenericArgumentLocation.Signature, 0, true),
                TypeSearch.Void);

            Assert.IsNotNull(method8);
        }