in (modyfikator ogólny) (odwołanie w C#)
W przypadku parametrów typu ogólnego słowo kluczowe określa, in
że parametr typu jest kontrawariantny. Słowo kluczowe można użyć in
w interfejsach ogólnych i delegatach.
Kontrawariancja umożliwia użycie mniej pochodnego typu niż określony przez parametr ogólny. Umożliwia to niejawną konwersję klas implementujących interfejsy kontrawariantne i niejawną konwersję typów delegatów. Kowariancja i kontrawariancja w parametrach typu ogólnego są obsługiwane dla typów odwołań, ale nie są obsługiwane dla typów wartości.
Typ można zadeklarować jako kontrawariant w interfejsie ogólnym lub delegować tylko wtedy, gdy definiuje typ parametrów metody, a nie typu zwracanego metody. In
parametry , ref
i out
muszą być niezmienne, co oznacza, że nie są kowariantne ani kontrawariantne.
Interfejs, który ma kontrawariantny parametr typu, umożliwia jego metodom akceptowanie argumentów mniej pochodnych typów niż te określone przez parametr typu interfejsu. Na przykład w interfejsie IComparer<T> typ T jest kontrawariantny, można przypisać obiekt typu do obiektu IComparer<Person>
IComparer<Employee>
typu bez użycia żadnych specjalnych metod konwersji, jeśli Employee
dziedziczy Person
.
Delegat kontrawariantny może być przypisany do innego delegata tego samego typu, ale z mniej pochodnym parametrem typu ogólnego.
Aby uzyskać więcej informacji, zobacz Covariance i Contravariance.
Interfejs ogólny contravariant
W poniższym przykładzie pokazano, jak deklarować, rozszerzać i implementować kontrawariantny interfejs ogólny. Pokazuje również, jak można użyć niejawnej konwersji dla klas implementujących ten interfejs.
// 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;
}
}
Kontrawariantny delegat ogólny
W poniższym przykładzie pokazano, jak zadeklarować, utworzyć wystąpienie i wywołać kontrawariantnego delegata ogólnego. Pokazuje również, jak można niejawnie przekonwertować typ delegata.
// 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());
}
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.