//
using System;
+using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
namespace System.Linq.Expressions {
static class Extensions {
+ public static bool IsGenericInstanceOf (this Type self, Type type)
+ {
+ if (!self.IsGenericType)
+ return false;
+
+ return self.GetGenericTypeDefinition () == type;
+ }
+
+ public static bool IsNullable (this Type self)
+ {
+ return self.IsValueType && self.IsGenericInstanceOf (typeof (Nullable<>));
+ }
+
+ public static bool IsExpression (this Type self)
+ {
+ return self == typeof (Expression) || self.IsSubclassOf (typeof (Expression));
+ }
+
+ public static bool IsGenericImplementationOf (this Type self, Type type, out Type generic_iface)
+ {
+ foreach (var iface in self.GetInterfaces ()) {
+ if (!iface.IsGenericInstanceOf (type))
+ continue;
+
+ generic_iface = iface;
+ return true;
+ }
+
+ generic_iface = null;
+ return false;
+ }
+
public static bool IsAssignableTo (this Type self, Type type)
{
- return type.IsAssignableFrom (self);
+ return type.IsAssignableFrom (self)
+ || ArrayTypeAreAssignable (self, type)
+ || ArrayTypeIsAssignableToInterface (self, type);
+ }
+
+ public static Type GetFirstGenericArgument (this Type self)
+ {
+ return self.GetGenericArguments () [0];
+ }
+
+ public static Type MakeGenericTypeFrom (this Type self, Type type)
+ {
+ return self.MakeGenericType (type.GetGenericArguments ());
+ }
+
+ public static Type MakeNullableType (this Type self)
+ {
+ return typeof (Nullable<>).MakeGenericType (self);
+ }
+
+ public static Type GetNotNullableType (this Type self)
+ {
+ return self.IsNullable () ? self.GetFirstGenericArgument () : self;
+ }
+
+ public static MethodInfo GetInvokeMethod (this Type self)
+ {
+ return self.GetMethod ("Invoke", BindingFlags.Public | BindingFlags.Instance);
+ }
+
+ public static MethodInfo MakeGenericMethodFrom (this MethodInfo self, MethodInfo method)
+ {
+ return self.MakeGenericMethod (method.GetGenericArguments ());
}
-/*
+
+ public static Type [] GetParameterTypes (this MethodBase self)
+ {
+ var parameters = self.GetParameters ();
+ var types = new Type [parameters.Length];
+
+ for (int i = 0; i < types.Length; i++)
+ types [i] = parameters [i].ParameterType;
+
+ return types;
+ }
+
+ static bool ArrayTypeAreAssignable (Type type, Type candidate)
+ {
+ if (!type.IsArray || !candidate.IsArray)
+ return false;
+
+ if (type.GetArrayRank () != candidate.GetArrayRank ())
+ return false;
+
+ return type.GetElementType ().IsAssignableTo (candidate.GetElementType ());
+ }
+
+ static bool ArrayTypeIsAssignableToInterface (Type type, Type candidate)
+ {
+ if (!type.IsArray)
+ return false;
+
+ if (!(candidate.IsGenericInstanceOf (typeof (IList<>)) || candidate.IsGenericInstanceOf (typeof (ICollection<>)) || candidate.IsGenericInstanceOf (typeof (IEnumerable<>))))
+ return false;
+
+ return type.GetElementType () == candidate.GetFirstGenericArgument ();
+ }
+
public static void OnFieldOrProperty (this MemberInfo self,
Action<FieldInfo> onfield, Action<PropertyInfo> onprop)
{
throw new ArgumentException ();
}
}
-*/
+
public static T OnFieldOrProperty<T> (this MemberInfo self,
Func<FieldInfo, T> onfield, Func<PropertyInfo, T> onprop)
{
throw new ArgumentException ();
}
}
+
+ public static Type MakeStrongBoxType (this Type self)
+ {
+ return typeof (StrongBox<>).MakeGenericType (self);
+ }
}
}