+
+ if (mono_class_has_variant_generic_params (klass)) {
+ if (oklass->generic_class) {
+ int i;
+ gboolean match = FALSE;
+ MonoClass *container_class1 = klass->generic_class->container_class;
+ MonoClass *container_class2 = oklass->generic_class->container_class;
+
+ /*
+ * Check whenever the generic definition of oklass implements the
+ * generic definition of klass. The IMPLEMENTS_INTERFACE stuff is not usable
+ * here since the relevant tables are not set up.
+ */
+ for (i = 0; i < container_class2->interface_offsets_count; ++i)
+ if ((container_class2->interfaces_packed [i] == container_class1) || (container_class2->interfaces_packed [i]->generic_class && (container_class2->interfaces_packed [i]->generic_class->container_class == container_class1)))
+ match = TRUE;
+
+ if (match) {
+ MonoGenericContainer *container;
+
+ container = klass->generic_class->container_class->generic_container;
+
+ match = TRUE;
+ for (i = 0; i < container->type_argc; ++i) {
+ MonoClass *param1_class = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [i]);
+ MonoClass *param2_class = mono_class_from_mono_type (oklass->generic_class->context.class_inst->type_argv [i]);
+
+ /*
+ * The _VARIANT and _COVARIANT constants should read _COVARIANT and
+ * _CONTRAVARIANT, but they are in a public header so we can't fix it.
+ */
+ if (param1_class != param2_class) {
+ if ((container->type_params [i].flags & MONO_GEN_PARAM_VARIANT) && mono_class_is_assignable_from (param1_class, param2_class))
+ ;
+ else if (((container->type_params [i].flags & MONO_GEN_PARAM_COVARIANT) && mono_class_is_assignable_from (param2_class, param1_class)))
+ ;
+ else
+ match = FALSE;
+ }
+ }
+
+ if (match)
+ return TRUE;
+ }
+ }
+ }