rspec/rules/S3246/csharp/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

65 lines
3.0 KiB
Plaintext

== Why is this an issue?
In the interests of making code as usable as possible, interfaces and delegates with generic parameters should use the ``++out++`` and ``++in++`` modifiers when possible to make the interfaces and delegates covariant and contravariant, respectively.
The ``++out++`` keyword can be used when the type parameter is used only as a return type in the interface or delegate. Doing so makes the parameter covariant, and allows interface and delegate instances created with a sub-type to be used as instances created with a base type. The most notable example of this is ``++IEnumerable<out T>++``, which allows the assignment of an ``++IEnumerable<string>++`` instance to an ``++IEnumerable<object>++`` variable, for instance.
The ``++in++`` keyword can be used when the type parameter is used only as a method parameter in the interface or a parameter in the delegate. Doing so makes the parameter contravariant, and allows interface and delegate instances created with a base type to be used as instances created with a sub-type. I.e. this is the inversion of covariance. The most notable example of this is the ``++Action<in T>++`` delegate, which allows the assignment of an ``++Action<object>++`` instance to a ``++Action<string>++`` variable, for instance.
=== Noncompliant code example
[source,csharp]
----
interface IConsumer<T> // Noncompliant
{
bool Eat(T fruit);
}
----
=== Compliant solution
[source,csharp]
----
interface IConsumer<in T>
{
bool Eat(T fruit);
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Add the "[in|out]" keyword to parameter "X" to make it "[covariant|contravariant]".
'''
== Comments And Links
(visible only on this page)
=== on 8 Jul 2015, 15:17:03 Ann Campbell wrote:
\[~tamas.vajk] note that the description I've written is for the "me" from last week. If it states too much of what is obvious to C# developers, please let me know what should be eliminated.
=== on 20 Jul 2015, 12:20:09 Tamas Vajk wrote:
\[~ann.campbell.2] I think the description is okay. We could shorten it, but it's not necessary. ``++in++`` and ``++out++`` is not used too often, so it's not necessarily common knowledge.
I've modified the description a bit. ``++IComparer++`` is not the most notable example for ``++in++`` generic arguments. We haven't discussed this, but this rule also applies for delegates with generic parameters. And the most notable example for ``++in++`` is the ``++Action++`` delegate: \https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx
A side note: the most notable example of having both ``++in++`` and ``++out++`` is probably the ``++Func<T, TResult>++`` delegate: \https://msdn.microsoft.com/en-us/library/bb549151(v=vs.110).aspx
=== on 20 Jul 2015, 14:09:21 Ann Campbell wrote:
Thanks [~tamas.vajk]. Note that I've just worked covariant/contravariant into the description in the appropriate places. I suddenly realized we described them but didn't actually attach the descriptions to the words!
endif::env-github,rspecator-view[]