예제 #1
0
        public void AccessField_BaseTypeConstraint()
        {
            var overriddenMethod = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.GenericMethod <Constraint> (null, ""));

            var type = AssembleType <DomainType> (
                p => p.GetOrAddOverride(overriddenMethod).SetBody(
                    ctx =>
            {
                // TODO 5480: Remove conversion and inline.
                var castedInstance = Expression.Convert(ctx.Parameters[0], typeof(Constraint));
                return(Expression.Block(
                           Expression.Assign(Expression.Field(castedInstance, "Field"), ctx.Parameters[1]),
                           Expression.Field(castedInstance, "Field")));
            }));

            var instance = (DomainType)Activator.CreateInstance(type);
            var arg      = new Constraint();

            var result = instance.GenericMethod(arg, "field on reference type");

            Assert.That(arg.Field, Is.EqualTo("field on reference type"));
            Assert.That(result, Is.EqualTo("field on reference type"));

            // Note that fields can only be accessed via a base type constraint. Since value types cannot be used as base type constraints, only fields
            // declared on reference types can be accessed from a generic parameter.
        }
예제 #2
0
        public void BaseMethod_GenericMethod()
        {
            var baseMethod = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType obj) => obj.GenericMethod <Dev.T> (null));

            var type = AssembleType <DomainType> (
                proxyType =>
            {
                var mutableMethod = proxyType.GetOrAddOverride(baseMethod);

                Assert.That(mutableMethod.BaseMethod, Is.SameAs(baseMethod));
                Assert.That(mutableMethod.IsGenericMethodDefinition, Is.True);
                var mutableGenericParameter = mutableMethod.MutableGenericParameters.Single();
                Assert.That(mutableGenericParameter.Name, Is.EqualTo("TPar"));
                Assert.That(mutableGenericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.None));
                Assert.That(mutableGenericParameter.GetGenericParameterConstraints(), Is.Empty);

                mutableMethod.SetBody(ctx => ExpressionHelper.StringConcat(ctx.PreviousBody, Expression.Constant(" made mutable")));
            });

            var method = GetDeclaredMethod(type, "GenericMethod");

            Assert.That(method.GetBaseDefinition(), Is.SameAs(baseMethod));
            Assert.That(method.IsGenericMethodDefinition, Is.True);
            var genericParameter = method.GetGenericArguments().Single();

            Assert.That(genericParameter.Name, Is.EqualTo("TPar"));
            Assert.That(genericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.None));
            Assert.That(genericParameter.GetGenericParameterConstraints(), Is.EqualTo(new[] { typeof(object) }), "Why object and not empty?");

            var instance = (DomainType)Activator.CreateInstance(type);

            Assert.That(instance.GenericMethod("doesn't matter"), Is.EqualTo("DomainType String made mutable"));
        }
예제 #3
0
        public void CreateBody_BuildsCorrectBody_UsingAbstractTemplateMembers()
        {
            var accessorImplementationMethod =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((PropertyAccessor a) => a.SetValue <object> (null));
            var arguments = new Expression[] { Expression.Parameter(typeof(int), "param") };
            var ctx       = new MethodBodyModificationContext(_proxyType, false, new ParameterExpression[0], Type.EmptyTypes, typeof(int), null, null);

            _interceptorPartialMock
            .Stub(stub => PrivateInvoke.GetNonPublicProperty(stub, "AccessorImplementationMethod"))
            .Return(accessorImplementationMethod);
            _interceptorPartialMock
            .Stub(stub => PrivateInvoke.InvokeNonPublicMethod(stub, "GetArguments", Arg <MethodBaseBodyContextBase> .Is.Anything))
            .WhenCalled(mi => Assert.That(mi.Arguments[0], Is.SameAs(ctx)))
            .Return(arguments);

            var result = (Expression)PrivateInvoke.InvokeNonPublicMethod(_interceptorPartialMock, "CreateBody", ctx);

            var expectedbody =
                Expression.Call(
                    Expression.Call(
                        Expression.Property(
                            new ThisExpression(_proxyType),
                            typeof(DomainObject).GetProperty("Properties", BindingFlags.Instance | BindingFlags.NonPublic)),
                        "get_Item",
                        null,
                        Expression.Constant("abc")),
                    "SetValue",
                    new[] { typeof(int) },
                    arguments);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedbody, result);
        }
예제 #4
0
        public void AccessMembers()
        {
            var overriddenMethod =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.GenericMethod <Constraint> (null, ""));
            var field    = NormalizingMemberInfoFromExpressionUtility.GetField((Constraint o) => o.Field);
            var method   = NormalizingMemberInfoFromExpressionUtility.GetMethod((Constraint o) => o.Method(""));
            var property = NormalizingMemberInfoFromExpressionUtility.GetProperty((Constraint o) => o.Property);

            var type = AssembleType <DomainType> (p => p.GetOrAddOverride(overriddenMethod).SetBody(ctx =>
            {
                var parameter = ctx.Parameters[0];
                var variable  = Expression.Variable(typeof(string));

                // TODO 5480: Remove conversion and inline.
                var castedParameter = Expression.Convert(parameter, typeof(Constraint));

                return(Expression.Block(
                           new[] { variable },
                           Expression.Assign(variable, Expression.Call(castedParameter, method, ctx.Parameters[1])),
                           Expression.Assign(Expression.Field(castedParameter, field), variable),
                           Expression.Assign(Expression.Property(castedParameter, property), Expression.Field(castedParameter, field)),
                           Expression.Property(castedParameter, property)));
            }));

            var instance = (DomainType)Activator.CreateInstance(type);
            var arg      = new Constraint();

            var result = instance.GenericMethod(arg, "abc");

            Assert.That(arg.Field, Is.EqualTo("method: abc"));
            Assert.That(arg.Property, Is.EqualTo("method: abc"));
            Assert.That(result, Is.EqualTo("method: abc"));
        }
예제 #5
0
        public void ExistingMethod()
        {
            var method = NormalizingMemberInfoFromExpressionUtility.GetMethod((DomainType o) => o.Method());
            var genericMethodDefiniton = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => Enumerable.Empty <Dev.T>());

            var type = AssembleType <DomainType> (
                p =>
                p.GetOrAddOverride(method)
                .SetBody(
                    ctx =>
            {
                var methodInstantiation = genericMethodDefiniton.MakeTypePipeGenericMethod(p);
                Assert.That(methodInstantiation.IsGenericMethod, Is.True);
                Assert.That(methodInstantiation.IsGenericMethodDefinition, Is.False);
                Assert.That(methodInstantiation.GetGenericArguments(), Is.EqualTo(new[] { p }));

                return(Expression.Call(methodInstantiation));
            }));

            var instance = (DomainType)Activator.CreateInstance(type);
            var result   = instance.Method();

            Assert.That(result, Is.InstanceOf <IEnumerable <DomainType> >());
            var resultType = result.GetType();

            Assert.That(resultType.IsArray, Is.True);
            Assert.That(resultType.GetElementType(), Is.SameAs(type));
        }
예제 #6
0
        public void GenericParameters()
        {
            var method1 = NormalizingMemberInfoFromExpressionUtility.GetMethod((DomainType o) => o.ReferenceType());
            var method2 = NormalizingMemberInfoFromExpressionUtility.GetMethod((DomainType o) => o.ValueType());
            var method3 = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.Unconstrained <Dev.T>());
            var method4 = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.ReferenceTypeConstraint <Dev.T>());
            var method5 = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.NotNuallableValueTypeConstraint <int>());
            var method6 = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.ClassBaseTypeConstraint <DomainType>());

            var type = AssembleType <DomainType> (
                proxyType =>
            {
                proxyType.GetOrAddOverride(method1).SetBody(ctx => Expression.Default(typeof(string)));
                proxyType.GetOrAddOverride(method2).SetBody(ctx => Expression.Default(typeof(int)));
                proxyType.GetOrAddOverride(method3).SetBody(ctx => Expression.Default(ctx.GenericParameters[0]));
                proxyType.GetOrAddOverride(method4).SetBody(ctx => Expression.Default(ctx.GenericParameters[0]));
                proxyType.GetOrAddOverride(method5).SetBody(ctx => Expression.Default(ctx.GenericParameters[0]));
                proxyType.GetOrAddOverride(method6).SetBody(ctx => Expression.Default(ctx.GenericParameters[0]));
            });

            var instance = (DomainType)Activator.CreateInstance(type);

            Assert.That(instance.ReferenceType(), Is.Null);
            Assert.That(instance.Unconstrained <string>(), Is.Null);
            Assert.That(instance.ReferenceTypeConstraint <string>(), Is.Null);
            Assert.That(instance.NotNuallableValueTypeConstraint <int>(), Is.EqualTo(0));
            Assert.That(instance.ClassBaseTypeConstraint <DomainType>(), Is.Null);
        }
예제 #7
0
        public void GetGenericMethodDefinition_Static()
        {
            var member = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => DomainType.StaticGenericMethod <TestClass> (null));

            var expected = typeof(DomainType).GetMethod("StaticGenericMethod");

            Assert.That(member, Is.EqualTo(expected));
        }
예제 #8
0
        public void GetGenericMethodDefinition_Instance_OverridingMethod()
        {
            var member = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType obj) => obj.OverridingGenericMethod <TestClass> (null));

            var expected = typeof(DomainType).GetMethod("OverridingGenericMethod");

            Assert.That(member, Is.EqualTo(expected));
        }
        public void GetMethodSignature_GenericMethod()
        {
            var method = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType obj) => obj.GenericMethod <int, int>());

            var result = SignatureDebugStringGenerator.GetMethodSignature(method);

            Assert.That(result, Is.EqualTo("Void GenericMethod[T1,T2]()"));
        }
예제 #10
0
        public void SetUp()
        {
            _genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T, Dev.T> (null));
            _typeArg1 = MutableTypeObjectMother.Create(typeof(object));
            _typeArg2 = MutableTypeObjectMother.Create(typeof(Exception));

            _instantiation = _genericMethodDefinition.MakeTypePipeGenericMethod(_typeArg1, _typeArg2);
        }
예제 #11
0
        public void AppendTypeString_GenericMethodParameter()
        {
            var method           = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType dt) => dt.MethodWithUsedGenericParameters <Dev.T, Dev.T>(null));
            var genericParameter = method.GetGenericArguments()[0];

            _helper.AppendTypeString(_sb, genericParameter);

            Assert.That(_sb.ToString(), Is.EqualTo("[0]"));
        }
        public static MethodInstantiation Create(MethodInfo genericMethodDefinition = null, IEnumerable <Type> typeArguments = null)
        {
            genericMethodDefinition = genericMethodDefinition
                                      ?? NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod(7));
            typeArguments = typeArguments ?? genericMethodDefinition.GetGenericArguments().Select(a => ReflectionObjectMother.GetSomeType());
            var instantiationInfo = new MethodInstantiationInfo(genericMethodDefinition, typeArguments);

            return(new MethodInstantiation(instantiationInfo));
        }
예제 #13
0
        public override void SetUp()
        {
            base.SetUp();

            _baseMethod = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.GenericMethod <C, D> (null, null));
            var genericParameters = _baseMethod.GetGenericArguments();

            _t1 = genericParameters[0];
            _t2 = genericParameters[1];
        }
        public void DelegateTo_Static_WithGenericParameters()
        {
            var context = MethodBodyContextBaseObjectMother.Create(genericParameters: _genericParameters);
            var method  = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => Enumerable.Empty <Dev.T>());

            var result = context.DelegateTo(null, method);

            Assert.That(result.Object, Is.Null);
            Assert.That(result.Method, Is.SameAs(method.MakeTypePipeGenericMethod(_genericParameters)));
        }
예제 #15
0
        public void IsGenericMethodInstantiation()
        {
            var nonGenericMethod        = ReflectionObjectMother.GetSomeNonGenericMethod();
            var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => Method <Dev.T, Dev.T>());
            var methodInstantiation     = NormalizingMemberInfoFromExpressionUtility.GetMethod(() => Method <int, string>());

            Assert.That(nonGenericMethod.IsGenericMethodInstantiation(), Is.False);
            Assert.That(genericMethodDefinition.IsGenericMethodInstantiation(), Is.False);
            Assert.That(methodInstantiation.IsGenericMethodInstantiation(), Is.True);
        }
        public void SetUp()
        {
            _genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T> (null));

            _customType  = CustomTypeObjectMother.Create();
            _runtimeType = ReflectionObjectMother.GetSomeType();

            _infoWithCustomType  = new MethodInstantiationInfo(_genericMethodDefinition, new[] { _customType }.AsOneTime());
            _infoWithRuntimeType = new MethodInstantiationInfo(_genericMethodDefinition, new[] { _runtimeType });
        }
예제 #17
0
        public void MakeTypePipeGenericType_UsesGenericArgumentUtilityToValidateGenericArguments()
        {
            var method = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => Method <Dev.T, Dev.T>());

            Assert.That(
                () => method.MakeTypePipeGenericMethod(typeof(int)),
                Throws.ArgumentException
                .With.ArgumentExceptionMessageEqualTo(
                    "The generic definition 'Method' has 2 generic parameter(s), but 1 generic argument(s) were provided. "
                    + "A generic argument must be provided for each generic parameter.", "typeArguments"));
        }
        public void Modify_Implicit_Generic()
        {
            var interfaceMethod = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((IDomainInterface o) => o.GenericMethod <Dev.T>());
            var type            = AssembleType <DomainType> (
                p => p.GetOrAddImplementation(interfaceMethod)
                .SetBody(ctx => ExpressionHelper.StringConcat(ctx.PreviousBody, Expression.Constant(" modified"))));

            var instance = (IDomainInterface)Activator.CreateInstance(type);

            Assert.That(instance.GenericMethod <string> (), Is.EqualTo("DomainType.GenericMethod String modified"));
        }
예제 #19
0
        public void CallBase_MethodInstantiation()
        {
            var method = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.GenericMethod <Dev.T>());

            Assert.That(
                () => _context.CallBase(method),
                Throws.ArgumentException
                .With.ArgumentExceptionMessageEqualTo(
                    "Cannot perform base call on generic method definition. Construct a method instantiation "
                    + "with MethodInfoExtensions.MakeTypePipeGenericMethod.", "baseMethod"));
        }
예제 #20
0
        public void MakeTypePipeGenericMethod_MakesGenericMethodWithCustomTypeArgument()
        {
            var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => Method <Dev.T, Dev.T>());
            var runtimeType             = ReflectionObjectMother.GetSomeType();
            var customType = CustomTypeObjectMother.Create();

            var result = genericMethodDefinition.MakeTypePipeGenericMethod(runtimeType, customType);

            Assert.That(result.IsGenericMethod, Is.True);
            Assert.That(result.IsGenericMethodDefinition, Is.False);
            Assert.That(result.GetGenericArguments(), Is.EqualTo(new[] { runtimeType, customType }));
        }
예제 #21
0
        public void SubstituteGenericParameters_RemembersSubstitutedTypes()
        {
            var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T> (null, null));
            var instantiation           = MethodInstantiationObjectMother.Create(genericMethodDefinition, new[] { _typeArgument });

            var parameterTypes = instantiation.GetParameters().Select(p => p.ParameterType).ToList();

            Assert.That(parameterTypes, Has.Count.EqualTo(2));
            Assert.That(parameterTypes[0].GetGenericTypeDefinition(), Is.SameAs(typeof(List <>)));
            Assert.That(parameterTypes[0].GetGenericArguments().Single(), Is.SameAs(_typeArgument));
            Assert.That(parameterTypes[0], Is.SameAs(parameterTypes[1]));
        }
예제 #22
0
        public void AddMethod_MethodDeclaration()
        {
            var method =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType obj) => obj.MethodDeclaration <MemoryStream> (null));
            var declaration = MethodDeclaration.CreateEquivalent(method);
            var type        = AssembleType <DomainType> (p => p.AddMethod("GenericMethod", MethodAttributes.Public, declaration, ctx => Expression.Empty()));

            var genericMethod    = type.GetMethod("GenericMethod");
            var genericParameter = genericMethod.GetGenericArguments().Single();

            Assert.That(
                genericParameter.GenericParameterAttributes,
                Is.EqualTo(GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint));
            Assert.That(genericParameter.GetGenericParameterConstraints(), Is.EquivalentTo(new[] { typeof(object), typeof(IDisposable) }));
        }
        public void SetUp()
        {
            _typeArgument = ReflectionObjectMother.GetSomeType();

            var genericTypeDefinition = typeof(GenericType <>);

            _genericTypeParameter      = genericTypeDefinition.GetGenericArguments().Single();
            _declaringType             = TypeInstantiationObjectMother.Create(genericTypeDefinition, new[] { _typeArgument });
            _memberOnTypeInstantiation = MethodOnTypeInstantiationObjectMother.Create(_declaringType);

            var genericMethodDefinition = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(() => GenericMethod <Dev.T>());

            _genericMethodParameter = genericMethodDefinition.GetGenericArguments().Single();
            _methodInstantiation    = MethodInstantiationObjectMother.Create(genericMethodDefinition, typeArguments: new[] { _typeArgument });
        }
        public void DelegateToBase()
        {
            var declaringType = MutableTypeObjectMother.Create(typeof(BaseType));
            var baseMethod    = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((BaseType o) => o.BaseMethod <Dev.T> (null));
            var parameters    = new[] { Expression.Parameter(_genericParameters[0]) };
            var context       = MethodBodyContextBaseObjectMother.Create(
                declaringType, genericParameters: _genericParameters, parameterExpressions: parameters, baseMethod: baseMethod);

            var result = context.DelegateToBase(baseMethod);

            var expected = Expression.Call(
                new ThisExpression(declaringType),
                new NonVirtualCallMethodInfoAdapter(baseMethod.MakeTypePipeGenericMethod(_genericParameters)),
                parameters.Cast <Expression>());

            ExpressionTreeComparer.CheckAreEqualTrees(expected, result);
        }
        public void Override_Implicit_Generic()
        {
            var interfaceMethod =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((IBaseInterface o) => o.GenericBaseMethod <Dev.T>());
            var type = AssembleType <DomainType> (
                p => p.GetOrAddImplementation(interfaceMethod)
                .SetBody(
                    ctx =>
            {
                Assert.That(ctx.HasBaseMethod, Is.True);
                return(ExpressionHelper.StringConcat(ctx.PreviousBody, Expression.Constant(" implicitly overridden")));
            }));

            var instance = (IBaseInterface)Activator.CreateInstance(type);

            Assert.That(instance.GenericBaseMethod <int> (), Is.EqualTo("DomainType.GenericBaseMethod Int32 implicitly overridden"));
        }
예제 #26
0
        public void CreateVectorOfGenericParameter()
        {
            // public override T'[] CreateGenericVector<T'> () {
            //   return new T'[7];
            // }
            var method = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.CreateGenericVector <Dev.T>());
            var type   = AssembleType <DomainType> (
                p => p.GetOrAddOverride(method).SetBody(ctx => Expression.NewArrayBounds(ctx.GenericParameters[0], Expression.Constant(7))));

            var instance    = (DomainType)Activator.CreateInstance(type);
            var valueVector = instance.CreateGenericVector <int>();
            var refVector   = instance.CreateGenericVector <string>();

            var valueArrayType = valueVector.GetType();

            Assert.That(valueArrayType.GetElementType(), Is.SameAs(typeof(int)));
            Assert.That(valueArrayType.GetArrayRank(), Is.EqualTo(1));
            Assert.That(valueVector.Length, Is.EqualTo(7));
            Assert.That(refVector.GetType().GetElementType(), Is.SameAs(typeof(string)));
        }
예제 #27
0
        public void CallVirtualMethod()
        {
            var overriddenMethod =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.GenericMethod <Constraint> (null, ""));
            var virtualMethod = NormalizingMemberInfoFromExpressionUtility.GetMethod((Constraint o) => o.VirtualMethod(""));

            var type = AssembleType <DomainType> (
                p => p.GetOrAddOverride(overriddenMethod).SetBody(ctx =>
            {
                var castedParameter = Expression.Convert(ctx.Parameters[0], typeof(Constraint));
                return(Expression.Call(castedParameter, virtualMethod, ctx.Parameters[1]));
            }));

            var instance = (DomainType)Activator.CreateInstance(type);
            var arg      = new Constraint();

            var result = instance.GenericMethod(arg, "abc");

            Assert.That(result, Is.EqualTo("virtual method: abc"));
        }
예제 #28
0
        public void OverrideGenericMethod_OverrideWithSameConstraints_CallBase()
        {
            var overriddenMethod =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((BaseType o) => o.OverridableGenericMethod(Dev <Dev.T> .Dummy));
            var type = AssembleType <DerivedType> (
                proxyType =>
            {
                var mutableMethod = proxyType.AddMethod(
                    "OverridableGenericMethod",
                    MethodAttributes.Public | MethodAttributes.Virtual,
                    new[] { new GenericParameterDeclaration("TDerived", GenericParameterAttributes.ReferenceTypeConstraint) },
                    ctx => typeof(string),
                    ctx => new[] { new ParameterDeclaration(ctx.GenericParameters[0], "arg") },
                    ctx =>
                {
                    Assert.That(ctx.HasBaseMethod, Is.True);
                    Assert.That(ctx.BaseMethod, Is.EqualTo(overriddenMethod));

                    // We need to instantiate the base method with our own generic parameter before calling it.
                    var instantiatedBaseMethod = ctx.BaseMethod.MakeTypePipeGenericMethod(ctx.GenericParameters[0]);
                    return(ExpressionHelper.StringConcat(ctx.CallBase(instantiatedBaseMethod, ctx.Parameters[0]), Expression.Constant(" overridden")));
                });
                Assert.That(mutableMethod.BaseMethod, Is.EqualTo(overriddenMethod));
                Assert.That(mutableMethod.GetBaseDefinition(), Is.EqualTo(overriddenMethod));
                Assert.That(mutableMethod.AddedExplicitBaseDefinitions, Is.Empty);

                var methods = proxyType.GetMethods();
                Assert.That(methods.Where(mi => mi.Name == "OverridableGenericMethod"), Is.EqualTo(new[] { mutableMethod }));
                Assert.That(methods, Has.No.Member(typeof(DerivedType).GetMethod("OverridableGenericMethod")));
            });

            var genericMethod    = GetDeclaredMethod(type, "OverridableGenericMethod");
            var genericParameter = genericMethod.GetGenericArguments().Single();

            Assert.That(genericMethod.GetBaseDefinition(), Is.EqualTo(overriddenMethod));
            Assert.That(genericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.ReferenceTypeConstraint));

            var instance = (DerivedType)Activator.CreateInstance(type);

            Assert.That(instance.OverridableGenericMethod("test"), Is.EqualTo("BaseType test overridden"));
        }
        public void Implement_Generic()
        {
            var interfaceMethod = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition(
                (IAddedInterfaceWithGenericMethod obj) => obj.GenericAddedMethod <MemoryStream>());
            var type = AssembleType <DomainType> (
                proxyType =>
            {
                proxyType.AddInterface(typeof(IAddedInterfaceWithGenericMethod));
                var mutableMethod = proxyType.GetOrAddImplementation(interfaceMethod);

                Assert.That(mutableMethod.BaseMethod, Is.Null);
                Assert.That(mutableMethod.IsGenericMethodDefinition, Is.True);
                var mutableGenericParameter = mutableMethod.MutableGenericParameters.Single();
                Assert.That(mutableGenericParameter.Name, Is.EqualTo("TPar"));
                Assert.That(mutableGenericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint));
                Assert.That(mutableGenericParameter.GetGenericParameterConstraints(), Is.EqualTo(new[] { typeof(IDisposable) }));

                mutableMethod.SetBody(
                    ctx =>
                {
                    Assert.That(ctx.HasBaseMethod, Is.False);
                    Assert.That(ctx.HasPreviousBody, Is.False);

                    return(Expression.Constant("implemented"));
                });
            });

            var method = GetDeclaredMethod(type, "GenericAddedMethod");

            Assert.That(method.GetBaseDefinition(), Is.SameAs(method));
            Assert.That(method.IsGenericMethodDefinition, Is.True);
            var genericParameter = method.GetGenericArguments().Single();

            Assert.That(genericParameter.GetGenericParameterConstraints(), Is.EquivalentTo(new[] { typeof(object), typeof(IDisposable) }));
            Assert.That(genericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint));

            var instance = (IAddedInterfaceWithGenericMethod)Activator.CreateInstance(type);

            Assert.That(instance.GenericAddedMethod <MemoryStream>(), Is.EqualTo("implemented"));
        }
예제 #30
0
        public void GenericVectorInTypeInstantiation()
        {
            // public T'[] CopyGenericListToArray<T'> (List<T[]'> list) () {
            //   return list[0];
            // }
            var method = NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType o) => o.CopyGenericListToArray <Dev.T> (null));
            var type   = AssembleType <DomainType> (
                p => p.GetOrAddOverride(method).SetBody(ctx => Expression.Property(ctx.Parameters[0], "Item", Expression.Constant(0))));

            var instance  = (DomainType)Activator.CreateInstance(type);
            var valVector = new int[0];
            var refVector = new string[0];

            var result1 = instance.CopyGenericListToArray(new List <int[]> {
                valVector
            });
            var result2 = instance.CopyGenericListToArray(new List <string[]> {
                refVector
            });

            Assert.That(result1, Is.SameAs(valVector));
            Assert.That(result2, Is.SameAs(refVector));
        }