예제 #1
0
        /// <summary>
        /// Creates a dynamic method for creating instances of the given type.
        /// The given type must have a public parameterless constructor.
        /// </summary>
        /// <param name="type">The type of the instances to be created.</param>
        /// <returns>
        /// A dynamic method for creating instances of the given type.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// The given type is an interface, or is abstract,
        /// or does not have a public parameterless constructor.
        /// </exception>
        public static Func <object> CreateDelegate(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var constructor = (Func <object>)DelegateCache.GetOrAdd(type, x => DoCreateDelegate(type));

            return(constructor);
        }
예제 #2
0
        /// <summary>
        /// Creates a dynamic method for creating instances from the given <see cref="ConstructorInfo"/>
        /// and indicates whether to perform a arguments validation in the dynamic method.
        /// </summary>
        /// <param name="constructorInfo">The constructor from which instances will be created.</param>
        /// <param name="validateArguments">
        /// If <c>true</c>, the dynamic method will validate if the array of arguments is null
        /// and check the length of the array to avoid the exceptions such as
        /// <see cref="NullReferenceException"/> or <see cref="IndexOutOfRangeException"/>,
        /// an <see cref="ArgumentNullException"/> or <see cref="ArgumentException"/> will be thrown instead.
        /// </param>
        /// <returns>
        /// A dynamic method for creating instances from the given constructor, the method receives an
        /// array as the arguments of the constructor.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="constructorInfo"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The declaring type of the construcor is abstract.
        /// </exception>
        public static Func <object[], object> CreateDelegate(ConstructorInfo constructorInfo, bool validateArguments)
        {
            if (constructorInfo == null)
            {
                throw new ArgumentNullException("constructorInfo");
            }

            var identity    = new { constructorInfo, validateArguments };
            var constructor = (Func <object[], object>)DelegateCache.GetOrAdd(
                identity, x => DoCreateDelegate(constructorInfo, validateArguments));

            return(constructor);
        }
예제 #3
0
        /// <summary>
        /// Creates a dynamic method for getting the value of the given property.
        /// </summary>
        /// <typeparam name="TSource">The type of the intance from which to get the value.</typeparam>
        /// <typeparam name="TRet">The type of the return value.</typeparam>
        /// <param name="propertyInfo">
        /// The instance of <see cref="PropertyInfo"/> from which the dynamic method would be created.
        /// </param>
        /// <param name="nonPublic">
        /// Indicates whether to use the non-public property getter method.
        /// </param>
        /// <returns>
        /// A dynamic method for getting the value of the given property.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="propertyInfo"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// The property is an indexer.
        /// -or -
        /// The get accessor method from <paramref name="propertyInfo"/> cannot be retrieved.
        /// -or-
        /// <typeparamref name="TSource"/> is not <see cref="object"/>, and from which
        /// the declaring type the property is not assignable.
        /// -or-
        /// <typeparamref name="TRet"/> is not assignable from the property type.
        /// </exception>
        public static Func <TSource, TRet> CreateGetter <TSource, TRet>(PropertyInfo propertyInfo, bool nonPublic)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            var identity = new { propertyInfo, nonPublic, sourceType = typeof(TSource), returnType = typeof(TRet) };
            var getter   = (Func <TSource, TRet>)DelegateCache.GetOrAdd(
                identity, x => DoCreateGetter <TSource, TRet>(propertyInfo, nonPublic));

            return(getter);
        }
예제 #4
0
        /// <summary>
        /// Creates a dynamic method for setting the value of the given property.
        /// </summary>
        /// <typeparam name="TTarget">The type of the instance the property belongs to.</typeparam>
        /// <typeparam name="TValue">The type of the value to set.</typeparam>
        /// <param name="propertyInfo">
        /// The instance of <see cref="PropertyInfo"/> from which the dynamic method would be created.
        /// </param>
        /// <param name="nonPublic">
        /// Indicates whether to use the non-public property setter method.
        /// </param>
        /// <returns>
        /// A dynamic method for setting the value of the given property.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="propertyInfo"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// The property is an indexer.
        /// -or-
        /// The set accessor method from the <paramref name="propertyInfo"/> cannot be retrieved.
        /// -or-
        /// <typeparamref name="TTarget"/> is a value type.
        /// -or-
        /// <typeparamref name="TTarget"/> is not <see cref="object"/>, and from which
        /// the declaring type of <paramref name="propertyInfo"/> is not assignable.
        /// -or-
        /// <typeparamref name="TValue"/> is not <see cref="object"/>, and the type of property
        /// is not assignable from <typeparamref name="TValue"/>.
        /// </exception>
        /// <remarks>
        /// In order to set a property value on a value type succesfully, the value type must be boxed
        /// in and <see cref="object"/>, and unboxed from the object after the dynamic
        /// set mothod is called, e.g.
        /// <code>
        ///   object boxedStruct = new SomeStruct();
        ///   setter(s, "the value");
        ///   SomeStruct unboxedStruct = (SomeStruct)boxedStruct;
        /// </code>
        /// </remarks>
        public static Action <TTarget, TValue> CreateSetter <TTarget, TValue>(PropertyInfo propertyInfo, bool nonPublic)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            var identity = new { propertyInfo, nonPublic, targetType = typeof(TTarget), valueType = typeof(TValue) };
            var setter   = (Action <TTarget, TValue>)DelegateCache.GetOrAdd(
                identity, x => DoCreateSetter <TTarget, TValue>(propertyInfo, nonPublic));

            return(setter);
        }
예제 #5
0
        /// <summary>
        /// Creates a dynamic method for getting the value of the given field.
        /// </summary>
        /// <typeparam name="TSource">The type of the intance from which to get the value.</typeparam>
        /// <typeparam name="TRet">The type of the return value.</typeparam>
        /// <param name="fieldInfo">
        /// The instance of <see cref="FieldInfo"/> from which the dynamic method would be created.
        /// </param>
        /// <returns>
        /// A dynamic method for getting the value of the given field.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="fieldInfo"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// <typeparamref name="TSource"/> is not <see cref="object"/>, and from which
        /// the declaring type of the field is not assignable.
        /// -or-
        /// <typeparamref name="TRet"/> is not assignable from the type of the field.
        /// </exception>
        public static Func <TSource, TRet> CreateGetter <TSource, TRet>(FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
            {
                throw new ArgumentNullException("fieldInfo");
            }

            var identity = new { fieldInfo, sourceType = typeof(TSource), returnType = typeof(TRet) };
            var getter   = (Func <TSource, TRet>)DelegateCache.GetOrAdd(
                identity, x => DoCreateGetter <TSource, TRet>(fieldInfo));

            return(getter);
        }
예제 #6
0
        /// <summary>
        /// Creates a dynamic method for setting the value of the given field.
        /// </summary>
        /// <typeparam name="TTarget">The type of the instance the field belongs to.</typeparam>
        /// <typeparam name="TValue">The type of the field value to set.</typeparam>
        /// <param name="fieldInfo">
        /// The instance of <see cref="FieldInfo"/> from which the dynamic method would be created.
        /// </param>
        /// <returns>
        /// A dynamic method for setting the value of the given field.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="fieldInfo"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// <typeparamref name="TTarget"/> is a value type.
        /// -or-
        /// <typeparamref name="TTarget"/> is not <see cref="object"/>, and from which
        /// the declaring type of <paramref name="fieldInfo"/> is not assignable.
        /// -or-
        /// <typeparamref name="TValue"/> is not <see cref="object"/>, and the type of field
        /// is not assignable from <typeparamref name="TValue"/>.
        /// </exception>
        /// <remarks>
        /// In order to set a field on a value type succesfully, the value type must be boxed
        /// in and <see cref="object"/>, and unboxed from the object after the dynamic
        /// set mothod is called, e.g.
        /// <code>
        ///   object boxedStruct = new SomeStruct();
        ///   setter(s, "the value");
        ///   SomeStruct unboxedStruct = (SomeStruct)boxedStruct;
        /// </code>
        /// </remarks>
        public static Action <TTarget, TValue> CreateSetter <TTarget, TValue>(FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
            {
                throw new ArgumentNullException("fieldInfo");
            }

            var identity = new { fieldInfo, targetType = typeof(TTarget), valueType = typeof(TValue) };
            var setter   = (Action <TTarget, TValue>)DelegateCache.GetOrAdd(
                identity, x => DoCreateSetter <TTarget, TValue>(fieldInfo));

            return(setter);
        }
예제 #7
0
        /// <summary>
        /// Creates a dynamic method for invoking the method from the given <see cref="MethodInfo"/>
        /// and indicates whether to perform a arguments validation in the dynamic method.
        /// </summary>
        /// <param name="methodInfo">
        /// The instance of <see cref="MemberInfo"/> from which the dyanmic method is to be created.
        /// </param>
        /// <param name="validateArguments">
        /// If <c>true</c>, the dynamic method will validate if the instance or the array of arguments
        /// is null and check the length of the array to avoid the exceptions such as
        /// <see cref="NullReferenceException"/> or <see cref="IndexOutOfRangeException"/>,
        /// an <see cref="ArgumentNullException"/> or <see cref="ArgumentException"/> will be thrown instead.
        /// </param>
        /// <returns>
        /// The delegate has two parameters: the first for the object instance (will be ignored
        /// if the method is static), and the second for the arguments of the method (will be
        /// ignored if the method has no arguments)/
        /// The return value of the delegate will be <c>null</c> if the method has no return value.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="methodInfo"/> is null.</exception>
        public static Func <object, object[], object> CreateDelegate(
            MethodInfo methodInfo, bool validateArguments)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException("methodInfo");
            }

            var identity = new { methodInfo, validateArguments };
            var method   = (Func <object, object[], object>)DelegateCache.GetOrAdd(
                identity, x => DoCreateDelegate(methodInfo, validateArguments));

            return(method);
        }