- Timestamp:
- 11/30/15 15:12:34 (9 years ago)
- Location:
- branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs
r12012 r13422 131 131 let t = assemblyType.BuildType(type) 132 132 where t != null 133 where t.Is SubTypeOf(type)133 where t.IsAssignableTo(type) 134 134 where !t.IsNonDiscoverableType() 135 135 where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType) -
branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/SandboxApplicationManager.cs
r12012 r13422 264 264 let t = assemblyType.BuildType(type) 265 265 where t != null 266 where t.Is SubTypeOf(type)266 where t.IsAssignableTo(type) 267 267 where !t.IsNonDiscoverableType() 268 268 where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType) -
branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/TypeExtensions.cs
r12012 r13422 76 76 } 77 77 78 internal static bool Is SubTypeOf(this Type subType, Type baseType) {78 internal static bool IsAssignableTo(this Type subType, Type baseType) { 79 79 if (baseType.IsAssignableFrom(subType)) return true; 80 81 //check generics 80 82 if (!baseType.IsGenericType) return false; 83 if (RecursiveCheckGenericTypes(baseType, subType)) return true; 81 84 82 if (RecursiveCheckGenericTypes(baseType, subType)) return true;85 //check generic interfaces 83 86 IEnumerable<Type> implementedInterfaces = subType.GetInterfaces().Where(t => t.IsGenericType); 84 foreach (var implementedInterface in implementedInterfaces.Where(i => i.IsGenericType)) { 85 if (baseType.CheckGenericTypes(implementedInterface)) return true; 86 } 87 88 return false; 87 return implementedInterfaces.Any(implementedInterface => baseType.CheckGenericTypes(implementedInterface)); 89 88 } 90 89 91 90 private static bool RecursiveCheckGenericTypes(Type baseType, Type subType) { 92 91 if (!baseType.IsGenericType) return false; 93 if (!subType.IsGenericType) return false; 94 if (baseType.CheckGenericTypes(subType)) return true; 92 if (subType.IsGenericType && baseType.CheckGenericTypes(subType)) return true; 95 93 if (subType.BaseType == null) return false; 96 94 … … 102 100 var subTypeGenericTypeDefinition = subType.GetGenericTypeDefinition(); 103 101 if (baseTypeGenericTypeDefinition != subTypeGenericTypeDefinition) return false; 102 104 103 var baseTypeGenericArguments = baseType.GetGenericArguments(); 105 104 var subTypeGenericArguments = subType.GetGenericArguments(); … … 109 108 var subTypeGenericArgument = subTypeGenericArguments[i]; 110 109 111 if (baseTypeGenericArgument.IsGenericParameter ^ subTypeGenericArgument.IsGenericParameter) return false; 112 if (baseTypeGenericArgument == subTypeGenericArgument) continue; 113 if (!baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) return false; 110 //no generic parameters => concrete types => check for type equality (ignore co- and contravariance) 111 //for example List<int> is only a List<int>, IParameter<IItem> is not a base type of IParameter<DoubleValue> 112 if (!baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) { 113 if (baseTypeGenericArgument == subTypeGenericArgument) continue; 114 return false; 115 } 114 116 115 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) && 116 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) return false; 117 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) && 118 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) return false; 119 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) && 120 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) return false; 117 //baseTypeGenericArgument is a concrete type and the subTypeGenericArgument is a generic parameter 118 //for example List<int> is not a base type of List<T> 119 if (!baseTypeGenericArgument.IsGenericParameter && subTypeGenericArgument.IsGenericParameter) return false; 121 120 122 foreach (var baseTypeGenericParameterConstraint in baseTypeGenericArgument.GetGenericParameterConstraints()) { 123 if (!subTypeGenericArgument.GetGenericParameterConstraints().Any(t => baseTypeGenericParameterConstraint.IsAssignableFrom(t))) return false; 121 //baseTypeGenericArugment is a generic parameter and the subTypeGenericArgument is a concrete type => check type constraints 122 //for example IParameter<T> is a base type of IParameter<IItem> if all generic contraints on T are fulfilled 123 if (baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) { 124 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) && 125 subTypeGenericArgument.IsValueType) return false; 126 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) && 127 subTypeGenericArgument.GetConstructor(Type.EmptyTypes) == null) return false; 128 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) { 129 if (!subTypeGenericArgument.IsValueType) return false; 130 if (subTypeGenericArgument.IsGenericType && subTypeGenericArgument.GetGenericTypeDefinition() == typeof(Nullable<>)) 131 return false; 132 } 133 134 //not assignable if the subTypeGenericArgument is not assignable to all of the constraints of the base type 135 if (baseTypeGenericArgument.GetGenericParameterConstraints().Any(baseTypeGenericParameterConstraint => 136 !baseTypeGenericParameterConstraint.IsAssignableFrom(subTypeGenericArgument))) 137 return false; 138 } 139 140 //both generic arguments are generic parameters => check type constraints 141 //for example IParameter<T> is a base type of IParameter<T> 142 if (baseTypeGenericArgument.IsGenericParameter && subTypeGenericArgument.IsGenericParameter) { 143 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) && 144 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) return false; 145 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) && 146 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) return false; 147 if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) && 148 !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) return false; 149 150 //not assignable if any of the constraints is not assignable to the constraints of the base type 151 if (baseTypeGenericArgument.GetGenericParameterConstraints().Any(baseTypeGenericParameterConstraint => !subTypeGenericArgument.GetGenericParameterConstraints().Any(t => baseTypeGenericParameterConstraint.IsAssignableFrom(t)))) { 152 return false; 153 } 124 154 } 125 155 }
Note: See TracChangeset
for help on using the changeset viewer.