
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.
114 lines
4.5 KiB
Plaintext
114 lines
4.5 KiB
Plaintext
== Why is this an issue?
|
|
|
|
In the interests of readability, code that can be simplified should be simplified. To that end, there are several ways ``++IEnumerable++`` language integrated queries (LINQ) can be simplified
|
|
|
|
* Use ``++OfType++`` instead of using ``++Select++`` with ``++as++`` to type cast elements and then null-checking in a query expression to choose elements based on type.
|
|
* Use ``++OfType++`` instead of using ``++Where++`` and the ``++is++`` operator, followed by a cast in a ``++Select++``
|
|
* Use an expression in ``++Any++`` instead of ``++Where(element => [expression]).Any()++``.
|
|
* Use ``++Count++`` instead of ``++Count()++`` when it's available.
|
|
* Don't call ``++ToArray()++`` or ``++ToList()++`` in the middle of a query chain.
|
|
|
|
Using ``++EntityFramework++`` may require enforcing client evaluations. Such queries should use ``++AsEnumerable()++`` instead of ``++ToArray()++`` or ``++ToList()++`` in the middle of a query chain.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,csharp]
|
|
----
|
|
seq1.Select(element => element as T).Any(element => element != null); // Noncompliant; use OfType
|
|
seq2.Select(element => element as T).Any(element => element != null && CheckCondition(element)); // Noncompliant; use OfType
|
|
seq3.Where(element => element is T).Select(element => element as T); // Noncompliant; use OfType
|
|
seq4.Where(element => element is T).Select(element => (T)element); // Noncompliant; use OfType
|
|
seq5.Where(element => [expression]).Any(); // Noncompliant; use Any([expression])
|
|
|
|
var num = seq6.Count(); // Noncompliant
|
|
var arr = seq.ToList().ToArray(); //Noncompliant
|
|
var count = seq.ToList().Count(x=>[condition]); //Noncompliant
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,csharp]
|
|
----
|
|
seq1.OfType<T>().Any();
|
|
seq2.OfType<T>().Any(element => CheckCondition(element));
|
|
seq3.OfType<T>();
|
|
seq4.OfType<T>();
|
|
seq5.Any(element => [expression])
|
|
|
|
var num = seq6.Count;
|
|
var arr = seq.ToArray();
|
|
var count = seq.Count(x=>[condition]);
|
|
----
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
* Use "OfType<T>()" here instead.
|
|
* Drop "Where" and move the condition into the "Any".
|
|
* Drop "ToArray" from the middle of the call chain.
|
|
* Replace "ToArray" with "AsEnumerable" in the middle of the call chain.
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== on 8 Jun 2015, 08:36:45 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] I've changed the description and the code samples of this RSPEC. Can you go through it? Thanks.
|
|
|
|
=== on 8 Jun 2015, 11:58:09 Ann Campbell wrote:
|
|
\[~tamas.vajk] I've made some edits to the description in an attempt to tighten it up a little. Please double-check me.
|
|
|
|
=== on 8 Jun 2015, 12:10:03 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] Thanks, it looks good.
|
|
|
|
=== on 9 Jun 2015, 14:09:32 Ann Campbell wrote:
|
|
see what you think [~tamas.vajk]
|
|
|
|
=== on 19 Jun 2015, 09:15:08 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] The description seems okay now.
|
|
|
|
But i have a problem with the R# keys. This rule covers quite a lot of R# rules, and I can't put all the code in the field, probably because I reach the max length. :-(
|
|
|
|
|
|
|
|
=== on 19 Jun 2015, 13:07:16 Ann Campbell wrote:
|
|
\[~tamas.vajk] you are hitting a max length. Fortunately, patterns work here. :-)
|
|
|
|
|
|
See the FindBugs field in RSPEC-2275 for an example.
|
|
|
|
=== on 8 Jul 2015, 09:04:08 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] I've modified the last point as it is not specific to ``++Count++``.
|
|
|
|
|
|
But a now that I'm thinking about it, we will have exceptions to this rule.
|
|
|
|
In case of ``++seq.ToList().Count(e=> condition)++`` or ``++seq.ToList().Where(e=> condition)++``, it doesn't make sense to call the ``++ToList++``. But ``++seq.ToList().Count()++`` is faster then ``++seq.Count()++`` because internally it uses a single call to the ``++Count++`` property, which is present on a list. (However, in this case we shouldn't use ``++.Count()++``, but ``++.Count++``.)
|
|
|
|
|
|
So we might want to add an additional covered case:
|
|
|
|
* using ``++.Count()++`` doesn't make sense on ``++IEnumerable++``s that are known to be of a derived type that has the more performant ``++.Count++`` property.
|
|
|
|
WDYT?
|
|
|
|
=== on 8 Jul 2015, 14:27:32 Ann Campbell wrote:
|
|
I've added the ``++Count()++``/``++Count++`` case.
|
|
|
|
|
|
Do we need to add an exception? If so, I need some help on the wording: under what circumstances is ``++ToList().Count++`` faster? Always? If so, we can just add that "except when..." to the relevant case.
|
|
|
|
=== on 20 Jul 2015, 12:02:09 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] Looks good. We don't need the exception now that we have the additional ``++Count++`` case.
|
|
|
|
endif::env-github,rspecator-view[]
|