/// <summary>
        /// Tries to invoke the specified member.
        /// </summary>
        /// <param name="binder">The binder.</param>
        /// <param name="args">The member's arguments.</param>
        /// <param name="result">The result, if any.</param>
        /// <returns><see langword="true"/> if the member is invoked; otherwise, <see langword="false"/>.</returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out result) != null);

            Contract.Assume(binder != null);
            Contract.Assume(args != null);

#if PORT_40
            var method = source.GetType().GetMethod(binder.Name, args.Select(a => a.GetType()).ToArray());
#elif WINDOWS_PHONE || PORT_45
            var argTypes = args.Select(a => a.GetType()).ToList();

            var method = source.GetType().GetTypeInfo().GetDeclaredMethods(binder.Name).SingleOrDefault(
                m => m.GetParameters().Length == argTypes.Count &&
                m.GetParameters().Zip(argTypes, (p, arg) => p.ParameterType.GetTypeInfo().IsAssignableFrom(arg.GetTypeInfo())).All(b => b));
#else
            var method = source.GetType().GetMethod(
                binder.Name,
                BindingFlags.Public | BindingFlags.Instance,
                Type.DefaultBinder,
                args.Select(a => a.GetType()).ToArray(),
                null);
#endif

            if (method == null)
            {
                result = null;
                return(false);
            }

            Func <object, object[], object> invoke = method.Invoke;

            var invokeAsync = invoke.ToAsync();

            IObservable <object> observable = invokeAsync(source, args);

            Contract.Assume(observable != null);

            if (method.ReturnType == typeof(void))
            {
                result = observable.Coerce(typeof(Unit));
            }
            else
            {
                result = observable.Coerce(method.ReturnType);
            }

            return(true);
        }
        private bool TryGetPropertyObservable(string propertyName, StringComparison comparison, out object result)
        {
            Contract.Requires(propertyName != null);
            Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out result) != null);

            var property = ComponentReflection.GetProperty(source, propertyName, comparison);

            if (property == null)
            {
                result = null;
                return(false);
            }

            var changed = property.PropertyChanged(source).Select(_ => property.GetValue(source));

#if !SILVERLIGHT
            Contract.Assume(property.PropertyType != null);
#endif

            result = changed.Coerce(property.PropertyType);

            return(true);
        }
        private bool TryGetEventObservable(string eventName, StringComparison comparison, out object result)
        {
            Contract.Requires(eventName != null);
            Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out result) != null);

            var @event = ComponentReflection.GetEvent(source, eventName, comparison);

            if (@event == null)
            {
                result = null;
                return(false);
            }

#if !SILVERLIGHT
            Contract.Assume(@event.EventType != null);
#endif

#if WINDOWS_PHONE || PORT_45
            var isGeneric = @event.EventType.GetTypeInfo().IsGenericType;
#else
            var isGeneric = @event.EventType.IsGenericType;
#endif

            Type eventArgsType;

            if (@event.EventType == typeof(EventHandler))
            {
                eventArgsType = typeof(EventArgs);
            }
            else if (!isGeneric || @event.EventType.GetGenericTypeDefinition() != typeof(EventHandler <>))
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.CurrentCulture, Errors.EventIsNotCompatibleWithEventHandler, eventName),
                          "eventName");
            }
            else
            {
#if WINDOWS_PHONE || PORT_45
                eventArgsType = @event.EventType.GetTypeInfo().GenericTypeArguments[0];
#else
                eventArgsType = @event.EventType.GetGenericArguments()[0];
#endif

                Contract.Assume(eventArgsType != null);

#if WINDOWS_PHONE || PORT_45
                var assignable = typeof(EventArgs).GetTypeInfo().IsAssignableFrom(eventArgsType.GetTypeInfo());
#else
                var assignable = typeof(EventArgs).IsAssignableFrom(eventArgsType);
#endif

                if (!assignable)
                {
                    throw new ArgumentException(
                              string.Format(CultureInfo.CurrentCulture, Errors.EventIsNotCompatibleWithEventArgs, eventName),
                              "eventName");
                }
            }

            result = @event.EventRaised(source).Coerce(eventArgsType);

            return(true);
        }
예제 #4
0
 //
 // Summary:
 //     Initializes a new instance of the System.Nullable<T> structure to the specified
 //     value.
 //
 // Parameters:
 //   value:
 //     A value type.
 public Nullable(T value)
 {
     Contract.Ensures(Contract.ValueAtReturn(out this).HasValue);
 }