Condividi tramite


in (modificatore generico) (Riferimenti per C#)

Per i parametri di tipo generico, la in parola chiave specifica che il parametro di tipo è controvariante. È possibile usare la in parola chiave in interfacce e delegati generici.

La controvarianza consente di usare un tipo meno derivato di quello specificato dal parametro generico. Ciò consente la conversione implicita di classi che implementano interfacce controvarianti e la conversione implicita dei tipi delegati. La Covarianza e la controvarianza nei parametri di tipo generico sono supportate per i tipi di riferimento, ma non sono supportate per i tipi valore.

Un tipo può essere dichiarato controvariante in un'interfaccia o delegato generico solo se definisce il tipo di parametri di un metodo e non del tipo restituito di un metodo. InI parametri , refe out devono essere invarianti, ovvero non sono né covarianti né controvarianti.

Un'interfaccia con un parametro di tipo controvariante consente ai relativi metodi di accettare argomenti di tipi meno derivati rispetto a quelli specificati dal parametro del tipo di interfaccia. Nell'interfaccia IComparer<T> , ad esempio, il tipo T è controvariante, è possibile assegnare un oggetto del IComparer<Person> tipo a un oggetto del IComparer<Employee> tipo senza utilizzare metodi di conversione speciali se Employee eredita Person.

A un delegato controvariante può essere assegnato un altro delegato dello stesso tipo, ma con un parametro di tipo generico meno derivato.

Per altre informazioni, vedere Covarianza e Controvarianza.

Interfaccia generica controvariante

Nell'esempio seguente viene illustrato come dichiarare, estendere e implementare un'interfaccia generica controvariante. Illustra anche come usare la conversione implicita per le classi che implementano questa interfaccia.

// 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;
    }
}

Delegato generico controvariante

Nell'esempio seguente viene illustrato come dichiarare, creare un'istanza e richiamare un delegato generico controvariante. Viene inoltre illustrato come convertire in modo implicito un tipo delegato.

// 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());
}

Specificazione del linguaggio C#

Per altre informazioni, vedere la specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Vedere anche