Example #1
0
        // this function utilizes the template type loader to generate new
        // EqualityComparer types on the fly
        private static object GetComparer(RuntimeTypeHandle t)
        {
            RuntimeTypeHandle comparerType;
            RuntimeTypeHandle openComparerType     = default(RuntimeTypeHandle);
            RuntimeTypeHandle comparerTypeArgument = default(RuntimeTypeHandle);

            if (RuntimeAugments.IsNullable(t))
            {
                RuntimeTypeHandle nullableType = RuntimeAugments.GetNullableType(t);
                if (ImplementsIEquatable(nullableType))
                {
                    openComparerType     = typeof(NullableEqualityComparer <>).TypeHandle;
                    comparerTypeArgument = nullableType;
                }
            }
            if (IsEnum(t))
            {
                openComparerType     = typeof(EnumEqualityComparer <>).TypeHandle;
                comparerTypeArgument = t;
            }

            if (openComparerType.Equals(default(RuntimeTypeHandle)))
            {
                if (ImplementsIEquatable(t))
                {
                    openComparerType     = typeof(GenericEqualityComparer <>).TypeHandle;
                    comparerTypeArgument = t;
                }
                else
                {
                    openComparerType     = typeof(ObjectEqualityComparer <>).TypeHandle;
                    comparerTypeArgument = t;
                }
            }

            bool success = RuntimeAugments.TypeLoaderCallbacks.TryGetConstructedGenericTypeForComponents(openComparerType, new RuntimeTypeHandle[] { comparerTypeArgument }, out comparerType);

            if (!success)
            {
                Environment.FailFast("Unable to create comparer");
            }

            return(RuntimeAugments.NewObject(comparerType));
        }
Example #2
0
        public sealed override Object Invoke(Object thisObject, Object[] arguments)
        {
            Object value    = thisObject;
            bool   hasValue = (thisObject != null);

            switch (_id)
            {
            case NullableMethodId.GetType:
                CheckArgumentCount(arguments, 0);
                return(value.GetType());    // Note: this throws a NullReferenceException if hasValue is false. Well so does the desktop.

            case NullableMethodId.ToString:
                CheckArgumentCount(arguments, 0);
                return(hasValue ? value.ToString() : "");

            case NullableMethodId.Equals:
            {
                CheckArgumentCount(arguments, 1);
                Object other = arguments[0];
                if (!hasValue)
                {
                    return(other == null);
                }
                if (other == null)
                {
                    return(false);
                }
                return(value.Equals(other));
            }

            case NullableMethodId.GetHashCode:
                CheckArgumentCount(arguments, 0);
                return(hasValue ? value.GetHashCode() : 0);

            case NullableMethodId.Ctor:
            {
                // Constructor case is tricky. Our implementation of NewObject() does not accept Nullable<T>'s so this is one of those cases
                // where the constructor is responsible for both the allocation and initialization. Fortunately, we only have to return the boxed
                // version of Nullable<T> which conveniently happens to be equal to the value we were passed in.
                CheckArgumentCount(arguments, 1);
                RuntimeTypeHandle theT     = RuntimeAugments.GetNullableType(_nullableTypeHandle);
                Object            argument = RuntimeAugments.CheckArgument(arguments[0], theT);
                return(argument);
            }

            case NullableMethodId.get_HasValue:
                CheckArgumentCount(arguments, 0);
                return(hasValue);

            case NullableMethodId.get_Value:
                CheckArgumentCount(arguments, 0);
                if (!hasValue)
                {
                    throw new InvalidOperationException(SR.InvalidOperation_NoValue);
                }
                return(value);

            case NullableMethodId.GetValueOrDefault_0:
            {
                CheckArgumentCount(arguments, 0);
                if (hasValue)
                {
                    return(value);
                }
                RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(_nullableTypeHandle);
                return(RuntimeAugments.NewObject(theT));
            }

            case NullableMethodId.GetValueOrDefault_1:
            {
                CheckArgumentCount(arguments, 1);
                RuntimeTypeHandle theT         = RuntimeAugments.GetNullableType(_nullableTypeHandle);
                Object            defaultValue = RuntimeAugments.CheckArgument(arguments[0], theT);
                return(hasValue ? value : defaultValue);
            }

            default:
                throw new InvalidOperationException();
            }
        }