{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/generic-type-inference-in-csharp","result":{"data":{"markdownRemark":{"html":"<p>Próbowałem ostatnio zrobić takie coś:</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">IWrapper<span class=\"token punctuation\">&lt;</span>TItem<span class=\"token punctuation\">></span></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token return-type class-name\">ICollection<span class=\"token punctuation\">&lt;</span>TItem<span class=\"token punctuation\">></span></span> Items <span class=\"token punctuation\">{</span><span class=\"token keyword\">get</span><span class=\"token punctuation\">;</span><span class=\"token keyword\">set</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyWrapper</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">IWrapper<span class=\"token punctuation\">&lt;</span>sting<span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">public</span> <span class=\"token return-type class-name\">ICollection<span class=\"token punctuation\">&lt;</span><span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span> Items<span class=\"token punctuation\">{</span><span class=\"token keyword\">get</span><span class=\"token punctuation\">;</span><span class=\"token keyword\">set</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Operator</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">public</span> <span class=\"token return-type class-name\">TWrapper</span> <span class=\"token generic-method\"><span class=\"token function\">DoSomething</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span>TWrapper<span class=\"token punctuation\">,</span> TItem<span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">where</span> <span class=\"token class-name\">TWrapper</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">IWrapper<span class=\"token punctuation\">&lt;</span>TItem<span class=\"token punctuation\">></span></span></span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// ...</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Następnie chciałem, żeby kompilator sam domyślił się drugiego argumentu generycznego, gdy wołam <code class=\"language-text\">DoSomething</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token keyword\">operator</span><span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">DoSomething</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span>Wrapper<span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>zamiast</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-csharp line-numbers\"><code class=\"language-csharp\"><span class=\"token keyword\">operator</span><span class=\"token punctuation\">.</span><span class=\"token generic-method\"><span class=\"token function\">DoSomething</span><span class=\"token generic class-name\"><span class=\"token punctuation\">&lt;</span>Wrapper<span class=\"token punctuation\">,</span> <span class=\"token keyword\">string</span><span class=\"token punctuation\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>Niestety, pierwsze opcja wywalała kompilację z komunikatem, że kompilator nie potrafi domyślić się typu tego drugiego argumentu generycznego. No ale - jak to? Skoro określam w <code class=\"language-text\">where</code>, że <code class=\"language-text\">TRequest</code> ma implementować interfejs <code class=\"language-text\">IWrapper&lt;TItem></code>, a <code class=\"language-text\">TItem</code> jest drugim argumentem, to chyba wiadomo, że np. dla <code class=\"language-text\">TRequest = IWapper&lt;int></code> - <code class=\"language-text\">TItem = int</code>?</p>\n<p>A jednak - nie! Jak zwykle odpowiedź przychodzi ze Stack Overflow - tym razem sam Eric Lippert, który pracował onegdaj przy kompilatorze C# <a href=\"https://stackoverflow.com/questions/8511066/why-doesnt-c-sharp-infer-my-generic-types/8511493#8511493\">wyjaśnia</a>, że:</p>\n<blockquote>\n<p>A bunch of people have pointed out that C# does not make inferences based on constraints. That is correct, and relevant to the question. Inferences are made by examining arguments and their corresponding formal parameter types and that is the only source of inference information.</p>\n</blockquote>\n<p>:(</p>","excerpt":"Próbowałem ostatnio zrobić takie coś: Następnie chciałem, żeby kompilator sam domyślił się drugiego argumentu generycznego, gdy wołam : zamiast Niestety…","frontmatter":{"date":"31 October, 2019","path":"/blog/generic-type-inference-in-csharp","title":"Generic type inference in C#"},"fields":{"readingTime":{"text":"1 min read"}}}},"pageContext":{}},"staticQueryHashes":["3649515864","63159454"]}