Condividi tramite


in (Modificatore generico) (Riferimenti per C#)

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

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

Un tipo può essere dichiarato controvariante in un'interfaccia o delegato generico se viene utilizzato solo come tipo di argomenti del metodo e non come tipo restituito dal metodo. I parametri Ref e out non possono essere variant.

Un'interfaccia che dispone di un parametro di tipo controvariante consente ai metodi di accettare argomenti di tipi meno derivati di quelli specificati dal parametro di tipo di interfaccia. Poiché, ad esempio, in .NET Framework 4, nell'interfaccia IComparer<T>, il tipo T è controvariante, è possibile assegnare un oggetto del tipo IComparer(Of Person) a un oggetto del tipo IComparer(Of Employee) senza utilizzare alcun metodo di conversione speciale 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 ulteriori informazioni, vedere Covarianza e controvarianza (C# e Visual Basic).

Esempio

Nell'esempio seguente viene illustrato come dichiarare, estendere e implementare un'interfaccia generica controvariante. Viene inoltre illustrato come sia possibile utilizzare 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;
    }
}

Nell'esempio seguente viene illustrato come dichiarare, creare un'istanza e richiamare un delegato generico controvariante. Viene inoltre illustrato come sia possibile 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()); 
}

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio è la fonte ufficiale per la sintassi e l'utilizzo di C#.

Vedere anche

Riferimenti

out (Modificatore generico) (Riferimenti per C#)

Modificatori (Riferimenti per C#)

Altre risorse

Covarianza e controvarianza (C# e Visual Basic)