public static bool IsKeyValuePairEnumerable(this Type type) { var iEnumerableType = typeof(IEnumerable <>); var keyValuePairType = typeof(KeyValuePair <,>); var interfaces = type.GetInterfaces(); foreach (var i in interfaces) { if (i.IsGenericType && i.GetGenericTypeDefinition() == iEnumerableType) { var arguments = i.GetGenericArguments(); if (arguments.Length != 1) { continue; } var a = arguments[0]; if (a.IsGenericType && a.GetGenericTypeDefinition() == keyValuePairType && a.GetGenericArguments().Length == 2) { return(KeyValuePairEnumerableObject.VerifyMethodRequirements(type)); } } } return(false); }
/// <summary> /// Create a new ClassBase-derived instance that implements a reflected /// managed type. The new object will be associated with a generated /// Python type object. /// </summary> private static ClassBase CreateClass(Type type) { // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsKeyValuePairEnumerable()) { impl = new KeyValuePairEnumerableObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else if (null != type.GetField("__pyobj__")) { impl = new ClassDerivedObject(type); } else { impl = new ClassObject(type); } return(impl); }