pascalabcnet/PABCNetHelp/LangGuide/Generics/covariance.html

51 lines
5.3 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Ковариантность">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Ковариантность параметров обобщенных типов</H1>
<p>Параметры обобщенного типа в C# могут быть объявлены ковариантными или
контравариантными. При описании обобщенного типа на C# ковариантный параметр
отмечается модификатором out, а контравариантный - модификатором in:</p>
<blockquote>
<pre class="wrap has-inner-focus" data-moniker=" dotnet-uwp-10.0 net-5.0 net-6.0 net-7.0 net-8.0 netcore-1.0 netcore-1.1 netcore-2.0 netcore-2.1 netcore-2.2 netcore-3.0 netcore-3.1 netframework-4.0 netframework-4.5 netframework-4.5.1 netframework-4.5.2 netframework-4.6 netframework-4.6.1 netframework-4.6.2 netframework-4.7 netframework-4.7.1 netframework-4.7.2 netframework-4.8 netframework-4.8.1 netstandard-1.0 netstandard-1.1 netstandard-1.2 netstandard-1.3 netstandard-1.4 netstandard-1.5 netstandard-1.6 netstandard-2.0 netstandard-2.1 xamarinandroid-7.1 xamarinios-10.8 xamarinmac-3.0 "><span><code class="csharp lang-csharp" data-author-content="public interface IEnumerable&lt;out T&gt; : System.Collections.IEnumerable" dir="ltr"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> </code><code data-author-content="public interface IEnumerable&lt;out T&gt; : System.Collections.IEnumerable" dir="ltr"><span class="hljs-title">IEnumerable</span>&lt;<span class="hljs-title">out</span> <span class="hljs-title">T</span></code><code class="csharp lang-csharp" data-author-content="public interface IEnumerable&lt;out T&gt; : System.Collections.IEnumerable" dir="ltr">&gt;</code></span></pre>
<pre class="wrap has-inner-focus" data-moniker=" dotnet-uwp-10.0 net-5.0 net-6.0 net-7.0 netcore-1.0 netcore-1.1 netcore-2.0 netcore-2.1 netcore-2.2 netcore-3.0 netcore-3.1 netframework-4.0 netframework-4.5 netframework-4.5.1 netframework-4.5.2 netframework-4.6 netframework-4.6.1 netframework-4.6.2 netframework-4.7 netframework-4.7.1 netframework-4.7.2 netframework-4.8 netstandard-1.0 netstandard-1.1 netstandard-1.2 netstandard-1.3 netstandard-1.4 netstandard-1.5 netstandard-1.6 netstandard-2.0 netstandard-2.1 xamarinandroid-7.1 xamarinios-10.8 xamarinmac-3.0 "><code class="csharp lang-csharp" data-author-content="public interface IComparer&lt;in T&gt;" dir="ltr"><span><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IComparer</span>&lt;<span class="hljs-title">in</span> <span class="hljs-title">T</span>&gt;</span></code></pre>
</blockquote>
<p>Ковариантный тип позволяет использовать вместо него любой производный класс,
а контравариантный - любой надкласс этого типа.</p>
<p>В PascalABC.NET можно лишо пользоваться обобщенными типами с ковариантными
параметрами из стандартной библиотеки .NET. Наиболее часто используемым
обобщенным типом с ковариантными параметрами является <span>
<code data-author-content="public interface IEnumerable&lt;out T&gt; : System.Collections.IEnumerable" dir="ltr">
<span class="hljs-title">IEnumerable</span>&lt;<span class="hljs-title">out</span>
<span class="hljs-title">T</span></code><code class="csharp lang-csharp" data-author-content="public interface IEnumerable&lt;out T&gt; : System.Collections.IEnumerable" dir="ltr">&gt;</code></span>,
который в PascalABC.NET представлен типом <code><strong>sequence of</strong> T</code>. </p>
<p>Основное использование ковариантности здесь заключается в том, что вместо <code>
<strong>sequence of</strong> Base</code> можно подставлять <code><strong>
sequence of</strong> Derived</code>, где <code>Derived</code> - производный
класс, а <code>Base</code> - базовый. Например:</p>
<blockquote>
<p><code><strong>begin</strong><br>&nbsp; <strong>var</strong> a: <strong>
sequence of</strong> object;<br>&nbsp; <strong>var</strong> b: <strong>
sequence of</strong> integer;<br>&nbsp; a := b;<br>&nbsp; a := Arr(1,2,3);<br>&nbsp;
a := new List&lt;DateTime&gt;;<br><strong>end</strong>.</code></p>
</blockquote>
<p>Следует обратить внимание, что <code>
<strong>array of</strong> integer</code> можно присвоить переменной типа <code>
<strong>sequence of</strong> integer</code> согласно принципу подстановки, а
<code>
<strong>sequence of</strong> integer</code> можно присвоить переменной типа
<code>
<strong>sequence of</strong> object</code>&nbsp; за счет ковариантности. Именно
поэтому присваивание <code>a := Arr(1,2,3)</code> допустимо.</p>
</body>
</html>