Esempio n. 1
0
        /// <summary>
        /// Gets the value of this property given the instance. If the property is <see langword="static"/>, pass <see langword="null"/> on the target.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the property has no getter or the target is <see langword="null"/> and the property is not <see langword="static"/></exception>
        /// <param name="target">The target instance. Pass <see langword="null"/> if the property is <see langword="static"/>.</param>
        /// <returns>The value of the property.</returns>
        public object?GetValue(object?target)
        {
            if (_get is null)
            {
                Throw.InvalidOperation($"The property {Member.DeclaringType}.{Member.Name} doesn't contain a getter.");
            }

            if (target is null && !IsStatic)
            {
                Throw.InvalidOperation($"The target cannot be null because {Member.DeclaringType}.{Member.Name} is not an static property.");
            }

            return(_get(target));
        }
Esempio n. 2
0
        public object CreateInstance()
        {
            if (_target.IsAbstract)
            {
                Throw.InvalidOperation("You cannot create an instance of an abstract type.");
            }

            if (Parameters.Count > 0)
            {
                Throw.InvalidOperation($"This constructor {_target.Name}({string.Join(", ", Parameters.Select(x => x.ParameterType.Name))}) requires these parameters to be used.");
            }

            return(Factory.CreateInstance(_target));
        }
Esempio n. 3
0
        public object CreateInstance([NotNull] params object[] args)
        {
            if (args is null)
            {
                Throw.NullArgument(nameof(args));
            }

            if (_target.IsAbstract)
            {
                Throw.InvalidOperation("You cannot create an instance of an abstract type.");
            }

            if (args.Length != Parameters.Count)
            {
                Throw.ParameterCountMismatch($"This constructor {_target.Name}({string.Join(", ", Parameters.Select(x => x.ParameterType.Name))}) requires these parameters to be used.");
            }

            for (var index = 0; index < args.Length; index++)
            {
                if (!args[index].GetType().CanBeConvertedTo(Parameters[index].ParameterType))
                {
                    Throw.InvalidOperation($"The type {args[index].GetType().Name} cannot be implicitly converted to {Parameters[index].ParameterType.Name}");
                }
            }

            if (_constructor is object)
            {
                return(_constructor(args));
            }

            var array = Expression.Parameter(typeof(object[]));

            var parameters = args
                             .Zip(Enumerable.Range(0, args.Length),
                                  (arg, index) => Expression.Convert(
                                      Expression.ArrayIndex(
                                          array,
                                          Expression.Constant(index)),
                                      arg.GetType()))
                             .ToArray();
            var @new    = Expression.New(Member, parameters);
            var convert = Expression.Convert(@new, typeof(object));

            _constructor = Expression.Lambda <Func <object[], object> >(convert, array).Compile();

            return(_constructor(args));
        }
Esempio n. 4
0
        /// <summary>
        /// Sets the value of this property given the instance and the value. If the property is <see langword="static"/>, pass <see langword="null"/> on the target.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the property has no setter, the target is <see langword="null"/> and the property is not <see langword="static"/> or the value is <see langword="null"/> and the property is not nullable.</exception>
        /// <param name="target">The target instance. Pass <see langword="null"/> if the property is <see langword="static"/>.</param>
        /// <param name="value">The value.</param>
        public void SetValue(object?target, object?value)
        {
            if (_set is null)
            {
                Throw.InvalidOperation($"The property {Member.DeclaringType}.{Member.Name} doesn't contain a setter.");
            }

            if (target is null && !IsStatic)
            {
                Throw.InvalidOperation($"The target cannot be null because {Member.DeclaringType}.{Member.Name} is not an static property.");
            }

            if (value is null && !IsNullable)
            {
                Throw.InvalidOperation($"The value cannot be null because {Member.DeclaringType}.{Member.Name} is of type {PropertyType}, which is not a nullable type (class, interface or Nullable<T>)");
            }

            _set(target, value);
        }