{"id":1391,"date":"2023-04-05T10:02:12","date_gmt":"2023-04-05T03:02:12","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=1391"},"modified":"2023-04-05T10:02:13","modified_gmt":"2023-04-05T03:02:13","slug":"csharp-contravariance","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-contravariance\/","title":{"rendered":"C# Contravariance"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about C# contravariance and how to use it to make your code more flexible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to C# Contravariance<\/h2>\n\n\n\n<p>Contravariance is a mechanism in C# that allows a method to accept a parameter of a less specific type than what is defined in the method signature. <\/p>\n\n\n\n<p>In other words, contravariance allows a method to accept an argument of a base <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-class\/\">class<\/a> or <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-interface\/\">interface<\/a> type, even if the parameter type is a derived class or interface type. C# uses the <code>in<\/code> keyword to define an interface as a contravariance.<\/p>\n\n\n\n<p>For example, you can define a generic interface as a contravariance like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">MyInterface<\/span>&lt;<span class=\"hljs-title\">in<\/span> <span class=\"hljs-title\">T<\/span>&gt;\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MyMethod<\/span>(<span class=\"hljs-params\">T item<\/span>)<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>in<\/code> keyword means that you can use the <code>T<\/code> as the type of parameters of methods. If you attempt to return a value of type <code>T<\/code>, you&#8217;ll get an error. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">MyInterface<\/span>&lt;<span class=\"hljs-title\">in<\/span> <span class=\"hljs-title\">T<\/span>&gt;\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MyMethod<\/span>(<span class=\"hljs-params\">T item<\/span>)<\/span>;\n    <span class=\"hljs-function\">T <span class=\"hljs-title\">ReturnItem<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>; <span class=\"hljs-comment\">\/\/ ERROR<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"note\">Note that to define <code>T<\/code> as the type of a return value, you use the <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-covariance\/\">covariance<\/a> instead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C# contravariance example<\/h2>\n\n\n\n<p>The following example demonstrates how contravariance works.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">using<\/span> <span class=\"hljs-keyword\">static<\/span> System.Console;\r\n\r\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span>\r\n{\r\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> Name\r\n    {\r\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\r\n    }\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Person<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name<\/span>)<\/span>\r\n    {\r\n        Name = name;\r\n    }\n\r\n}\r\n\r\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Employee<\/span> : <span class=\"hljs-title\">Person<\/span>\r\n{\r\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> JobTitle\r\n    {\r\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\r\n    }\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Employee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">string<\/span> jobTitle<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name<\/span>)<\/span>\r\n    {\r\n        JobTitle = jobTitle;\r\n    }\r\n\r\n}\r\n\r\n<span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IGroup<\/span>&lt;<span class=\"hljs-title\">in<\/span> <span class=\"hljs-title\">T<\/span>&gt;\r\n{\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Add<\/span>(<span class=\"hljs-params\">T item<\/span>)<\/span>;\r\n\r\n    <span class=\"hljs-keyword\">int<\/span> Count\r\n    {\r\n        <span class=\"hljs-keyword\">get<\/span>;\r\n    }\r\n}\r\n\r\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Group<\/span>&lt;<span class=\"hljs-title\">T<\/span>&gt; : <span class=\"hljs-title\">IGroup<\/span>&lt;<span class=\"hljs-title\">T<\/span>&gt;\r\n{\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> List&lt;T&gt; list = <span class=\"hljs-keyword\">new<\/span>();\r\n\r\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> Count =&gt; list.Count;\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Add<\/span>(<span class=\"hljs-params\">T item<\/span>)<\/span> =&gt; list.Add(item);\r\n\r\n}\r\n\r\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\r\n{\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Display<\/span>(<span class=\"hljs-params\">IGroup&lt;Employee&gt; <span class=\"hljs-keyword\">group<\/span><\/span>)<\/span>\r\n    {\r\n        WriteLine(<span class=\"hljs-keyword\">group<\/span>.Count);\r\n    }\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\r\n    {\r\n        IGroup&lt;Person&gt; <span class=\"hljs-keyword\">group<\/span> = <span class=\"hljs-keyword\">new<\/span> Group&lt;Person&gt;();\r\n        <span class=\"hljs-keyword\">group<\/span>.Add(<span class=\"hljs-keyword\">new<\/span> Person(<span class=\"hljs-string\">\"John Doe\"<\/span>));\r\n        <span class=\"hljs-keyword\">group<\/span>.Add(<span class=\"hljs-keyword\">new<\/span> Person(<span class=\"hljs-string\">\"Jane Doe\"<\/span>));\r\n\r\n        Display(<span class=\"hljs-keyword\">group<\/span>);\r\n    }\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">2<\/code><\/span><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define the <code>Person<\/code> class that has the <code>Name<\/code> property, and the <code>Employee<\/code> class that inherits from the <code>Person<\/code> class. The <code>Employee<\/code> class has additional <code>JobTitle<\/code> property.<\/p>\n\n\n\n<p>Next, define the <code>IGroup&lt;T><\/code> interface as contravariance by using the keyword <code>in<\/code>. The <code>IGroup&lt;T><\/code> has a method <code>Add()<\/code> and a <code>Count<\/code> property.<\/p>\n\n\n\n<p>Then, define the <code>Group&lt;T><\/code> class that implements the <code>IGroup&lt;T><\/code> interface. The <code>Add()<\/code> method adds an item with type <code>T<\/code> to a list and the <code>Count<\/code> property returns the number of items in the list.<\/p>\n\n\n\n<p>After that, define the <code>Display<\/code> method that accepts an instance of <code>IGroup&lt;Employee><\/code> and shows the number of items in the group to the console.<\/p>\n\n\n\n<p>Finally, create a group of <code>Person<\/code> objects and pass it to the <code>Display<\/code> method. Because the <code>IGroup&lt;T><\/code> is a contravariance, the program run successfully. <\/p>\n\n\n\n<p>But if you take out the <code>in<\/code> keyword from the <code>IGroup&lt;T><\/code> interface, the program won&#8217;t be compiled.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In C#, contravariance is a feature that allows a method to take an argument that is less specific than the one defined in the method signature.<\/li>\n\n\n\n<li>Use the keyword <code>in<\/code> to define an interface as a contravariance.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"1391\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-contravariance\/\"\n\t\t\t\tdata-post-title=\"C# Contravariance\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"1391\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-contravariance\/\"\n\t\t\t\tdata-post-title=\"C# Contravariance\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you&#8217;ll learn about C# contravariance and how to use it to make your code more flexible. Introduction to C# Contravariance Contravariance is a mechanism in C# that allows a method to accept a parameter of a less specific type than what is defined in the method signature. In other words, contravariance [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":7,"menu_order":68,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1391","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/comments?post=1391"}],"version-history":[{"count":1,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1391\/revisions"}],"predecessor-version":[{"id":1394,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1391\/revisions\/1394"}],"up":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/7"}],"wp:attachment":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/media?parent=1391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}