pascalabcnet/PABCNetHelp/LangGuide/Generics/covariance.html

51 lines
5.3 KiB
HTML
Raw Permalink Normal View History

<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>