/// <summary> /// Constructor used for the top-level search /// </summary> /// <param name="type"></param> /// <param name="owner"></param> public TargetTypeSelectorParams(Type type, TargetTypeSelector owner) : this(type) { RootTargets = owner?.RootTargets; // variance always starts off enabled. EnableVariance = true; bool enableContravariance = true; this._forceContravariance = GetInternalContravarianceOverride(Type); if (this._forceContravariance == null) { if (RootTargets != null) { enableContravariance = RootTargets.GetOption( Type, Options.EnableContravariance.Default); } } else { enableContravariance = this._forceContravariance.Value; } if (enableContravariance) { Contravariance = Contravariance.BasesAndInterfaces; } else { Contravariance = Contravariance.None; } }
public TargetTypeSelectorParams(Type type, Type typeParameter = null, TargetTypeSelectorParams parent = null, Contravariance?contravariantSearchType = null) : this(type) { Parent = parent; RootTargets = parent?.RootTargets; TypeParameter = typeParameter; // We enable variance if we have no parent // Or if we have a variant type parameter and // the parent hasn't disabled variance. EnableVariance = parent == null || (TypeParameterIsVariant && Parent.EnableVariance); if (EnableVariance) { bool enableContravariance; if (ForceContravariance == null) { // start off always enabled enableContravariance = true; var overridenContravariance = GetInternalContravarianceOverride(Type); if (overridenContravariance != null) { // once it's forced, all child searches will avoid testing the EnableContravariance option this._forceContravariance = overridenContravariance; enableContravariance = overridenContravariance.Value; } else if (RootTargets != null) { enableContravariance = RootTargets.GetOption( Type, Options.EnableContravariance.Default); } } else { enableContravariance = ForceContravariance.Value; } if (contravariantSearchType != null) { Contravariance = contravariantSearchType.Value; } else { if (!enableContravariance) { Contravariance = Contravariance.None; } else { // if the parent has its contravariance search set to None, we inherit that // and move on. if (Parent?.Contravariance == Contravariance.None) { Contravariance = Contravariance.None; } else { var numContras = TypeParameterChain.Count(t => t.IsContravariantTypeParameter()); if (numContras <= 1 || (numContras % 2) == 1) { Contravariance = Contravariance.BasesAndInterfaces; } else { Contravariance = Contravariance.Derived; } } } } } }