1 //----------------------------------------------------------------
2 // <copyright company="Microsoft Corporation">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //----------------------------------------------------------------
7 namespace System.Activities.Presentation
9 using System.Reflection;
12 internal static class TypeUtilities
14 // returns true if the generic parameter can be subsituted by the candidate.
15 // Sometime if the generic parameter is too complex, this method will return a false positive, but it's fine.
16 public static bool CanSubstituteGenericParameter(Type genericParameter, Type candidate)
18 Fx.Assert(genericParameter != null, "genericParameter should not be null");
19 Fx.Assert(genericParameter.IsGenericParameter == true, "genericParameter should be a valid generic parameter");
21 if (ContainsAnyFlag(genericParameter.GenericParameterAttributes, GenericParameterAttributes.SpecialConstraintMask))
23 if (ContainsAnyFlag(genericParameter.GenericParameterAttributes, GenericParameterAttributes.ReferenceTypeConstraint))
25 if (!candidate.IsClass && !candidate.IsInterface)
31 if (ContainsAnyFlag(genericParameter.GenericParameterAttributes, GenericParameterAttributes.DefaultConstructorConstraint))
33 if (!TypeUtilities.CanCreateInstanceUsingDefaultConstructor(candidate))
39 if (ContainsAnyFlag(genericParameter.GenericParameterAttributes, GenericParameterAttributes.NotNullableValueTypeConstraint))
41 if (!candidate.IsValueType)
46 if (candidate.IsGenericType && candidate.GetGenericTypeDefinition() != typeof(Nullable<>))
53 foreach (Type constraint in genericParameter.GetGenericParameterConstraints())
55 if (constraint.ContainsGenericParameters)
57 // return true for all types because we don't have a good way to find out if the candidate is good or not.
58 // The caller will try to create closed generic type which will tell if the candidate is really good or not.
62 if (!constraint.IsAssignableFrom(candidate))
71 public static bool CanCreateInstanceUsingDefaultConstructor(Type type)
73 Fx.Assert(type != null, "type could not be null");
75 return type.IsValueType || (!type.IsAbstract && type.GetConstructor(Type.EmptyTypes) != null);
78 public static bool IsTypeCompatible(Type childObjectType, Type parentObjectType)
80 if (!parentObjectType.IsGenericTypeDefinition)
82 return parentObjectType.IsAssignableFrom(childObjectType);
84 else if (parentObjectType.IsInterface)
86 Type[] interfaceTypes = childObjectType.GetInterfaces();
87 foreach (Type interfaceType in interfaceTypes)
89 if (interfaceType.IsGenericType)
91 if (interfaceType.GetGenericTypeDefinition() == parentObjectType)
102 Type current = childObjectType;
103 while (current != null)
105 if (current.IsGenericType)
107 if (current.GetGenericTypeDefinition() == parentObjectType)
113 current = current.BaseType;
120 private static bool ContainsAnyFlag(GenericParameterAttributes attributes, GenericParameterAttributes flags)
122 return (attributes & flags) != GenericParameterAttributes.None;