in (modificateur générique) (Référence C#)
Pour les paramètres de type générique, le mot clé in
spécifie que le paramètre de type est contravariant. Vous pouvez utiliser le mot clé in
dans les interfaces et délégués génériques.
La contravariance permet d’utiliser un type moins dérivé que celui spécifié par le paramètre générique. Cela permet la conversion implicite des classes qui implémentent des interfaces contravariantes, ainsi que la conversion implicite des types délégués. La covariance et la contravariance des paramètres de type générique sont prises en charge pour les types référence, mais pas pour les types valeur.
Un type peut être déclaré comme étant contravariant dans une interface ou un délégué générique uniquement s’il définit le type des paramètres d’une méthode et non le type de retour d’une méthode. Les paramètres In
, ref
et out
doivent être invariants, ce qui signifie qu’ils ne sont ni covariants ni contravariants.
Une interface qui possède un paramètre de type contravariant permet à ses méthodes d’accepter des arguments de types moins dérivés que ceux spécifiés par le paramètre de type d’interface. Par exemple, dans l’interface IComparer<T>, le type T est contravariant, vous pouvez attribuer un objet du type IComparer<Person>
à un objet du type IComparer<Employee>
sans utiliser de méthode de conversion spéciale si Employee
hérite Person
.
Un délégué contravariant peut être assigné à un autre délégué du même type, mais avec un paramètre de type générique moins dérivé.
Pour plus d’informations, consultez Covariance et contravariance.
Interface générique contravariante
L’exemple suivant montre comment déclarer, étendre et implémenter une interface générique contravariante. Il montre également comment utiliser la conversion implicite pour les classes qui implémentent cette interface.
// Contravariant interface.
interface IContravariant<in A> { }
// Extending contravariant interface.
interface IExtContravariant<in A> : IContravariant<A> { }
// Implementing contravariant interface.
class Sample<A> : IContravariant<A> { }
class Program
{
static void Test()
{
IContravariant<Object> iobj = new Sample<Object>();
IContravariant<String> istr = new Sample<String>();
// You can assign iobj to istr because
// the IContravariant interface is contravariant.
istr = iobj;
}
}
Délégué générique contravariant
L’exemple de code suivant montre comment déclarer, instancier et invoquer un délégué générique contravariant. Il montre également comment convertir implicitement un type délégué.
// Contravariant delegate.
public delegate void DContravariant<in A>(A argument);
// Methods that match the delegate signature.
public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }
public void Test()
{
// Instantiating the delegates with the methods.
DContravariant<Control> dControl = SampleControl;
DContravariant<Button> dButton = SampleButton;
// You can assign dControl to dButton
// because the DContravariant delegate is contravariant.
dButton = dControl;
// Invoke the delegate.
dButton(new Button());
}
spécification du langage C#
Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.