Partilhar via


in (Modificador Genérico) (Referência C#)

Para parâmetros de tipo genéricos, a in palavra-chave especifica que o parâmetro type é contravariante. Você pode usar a in palavra-chave em interfaces genéricas e delegados.

A contravariância permite que você use um tipo menos derivado do que o especificado pelo parâmetro genérico. Isso permite a conversão implícita de classes que implementam interfaces contravariantes e a conversão implícita de tipos delegados. Covariância e contravariância em parâmetros de tipo genéricos são suportadas para tipos de referência, mas não são suportadas para tipos de valor.

Um tipo pode ser declarado contravariante em uma interface genérica ou delegar somente se definir o tipo de parâmetros de um método e não do tipo de retorno de um método. In, refe os parâmetros devem ser invariantes out , o que significa que não são covariantes nem contravariantes.

Uma interface que tem um parâmetro de tipo contravariante permite que seus métodos aceitem argumentos de tipos menos derivados do que aqueles especificados pelo parâmetro de tipo de interface. Por exemplo, na interface, o IComparer<T> tipo T é contravariante, você pode atribuir um objeto do IComparer<Person> tipo a um objeto do tipo sem usar nenhum método de IComparer<Employee> conversão especial se Employee herdar Person.

Um delegado contravariante pode ser atribuído a outro delegado do mesmo tipo, mas com um parâmetro de tipo genérico menos derivado.

Para obter mais informações, consulte Covariância e contravariância.

Interface genérica contravariante

O exemplo a seguir mostra como declarar, estender e implementar uma interface genérica contravariante. Ele também mostra como você pode usar a conversão implícita para classes que implementam essa 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;
    }
}

Delegado genérico contravariante

O exemplo a seguir mostra como declarar, instanciar e invocar um delegado genérico contravariante. Ele também mostra como você pode converter implicitamente um tipo de delegado.

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

Especificação da linguagem C#

Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso do C#.

Consulte também