Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Для параметров универсального типа используйте ключевое in слово, чтобы разрешить аргументы контравариантного типа. Используйте ключевое in слово в универсальных интерфейсах и делегатах.
Справочные документы по языку C# описывают последнюю выпущенную версию языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.
Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.
Подсказка
Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей об истории версий языка C#.
Контравариантность позволяет использовать менее производный тип, чем тип, указанный универсальным параметром. Эта функция позволяет неявно преобразовать классы, реализующие контравариантные интерфейсы и неявное преобразование типов делегатов. Ссылочные типы поддерживают ковариацию и контравариантность в параметрах универсального типа, но типы значений не поддерживают эти функции.
Тип можно объявить как контравариантный в универсальном интерфейсе или делегировать, только если он определяет тип параметров метода, а не возвращаемый тип метода.
In, refи out параметры должны быть инвариантными, то есть они не ковариантные или контравариантные.
Интерфейс с параметром контрвариантного типа позволяет своим методам принимать аргументы менее производных типов, чем указанные параметром типа интерфейса. Например, в интерфейсе IComparer<T> тип T является контравариантным. Объект типа можно назначить объекту IComparer<Person>IComparer<Employee> типа без использования специальных методов преобразования, если Employee наследуется Person.
Можно назначить контравариантный делегат другому делегату того же типа, но с менее производным параметром универсального типа.
Дополнительные сведения см. в разделе Ковариантность и контравариантность.
Универсальный интерфейс contravariant
В следующем примере показано, как объявить, расширить и реализовать контравариантный универсальный интерфейс. В нем также показано, как использовать неявное преобразование для классов, реализующих этот интерфейс.
// 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;
}
}
Универсальный делегат contravariant
В следующем примере показано, как объявить, создать экземпляр и вызвать контравариантный универсальный делегат. В нем также показано, как неявно преобразовать тип делегата.
// 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());
}
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является авторитетным источником синтаксиса и использования языка C#.
См. также
- наружу
- Ковариантность и контравариантность
- модификаторы