IEnumerable doesn't have a Count method - c#

I have the following method:
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations(){
//code here
}
Why is it that when I do .Count() above it is underlined in red?
I got the following error:
Error 1 'System.Collections.Generic.IEnumerable'
does not contain a definition for
'Count' and no extension method
'Count' accepting a first argument of
type
'System.Collections.Generic.IEnumerable'
could be found (are you missing a
using directive or an assembly
reference?) c:\users\a\documents\visual
studio
2010\Projects\NerdDinner\NerdDinner\Models\Dinner.cs 15 47 NerdDinner

You add:
using System.Linq;
at the top of your source and make sure you've got a reference to the System.Core assembly.
Count() is an extension method provided by the System.Linq.Enumerable static class for LINQ to Objects, and System.Linq.Queryable for LINQ to SQL and other out-of-process providers.
EDIT: In fact, using Count() here is relatively inefficient (at least in LINQ to Objects). All you want to know is whether there are any elements or not, right? In that case, Any() is a better fit:
public bool IsValid
{
get { return !GetRuleViolations().Any(); }
}

Any() or Count() methods in Linq work only for generic types.
IEnumerable<T>
If you have a simple IEnumerable without a type, try to use
IEnumerable<object>
instead.

IEnumeration does not have a method called Count(). It's just a kind of "sequence of elements". Use for example List if you explicitly need the number of elements.
If you use Linq keep in mind, that the extension method Count() may actually re-count the number of elements each time you call it.

A short & sweet general word of caution on the pitfalls of .Count() to help the weary traveler that stumbles upon this post in the future!
Short story:
The following works -no doubt- but there might small performance penalty if the enumerables is not backed by an underlying array or list which has the 'count' in handy/precomputed:
public bool IsValid
{
get { return SomeMethodReturningEnumerable().Count() <= threshold; } <--- small performance issue here
}
public IEnumerable<SomeObject> SomeMethodReturningEnumerable(){
yield return foo;
yield return bar; etc
}
The call to the .Count() method will probably go through each and every item in the enumerable and then compare the overall count against threshold. We being smarter can do a bit better:
public bool IsValid
{
get { return !SomeMethodReturningEnumerable().HasMoreThan(threshold); } <--- neato!
}
public static bool HasLessThan<T>(this IEnumerable<T> sequence, int count) => !sequence.HasMoreThan(count - 1);
public static bool HasLessOrEqualTo<T>(this IEnumerable<T> sequence, int count) => !sequence.HasMoreThan(count);
public static bool HasMoreOrEqualTo<T>(this IEnumerable<T> sequence, int count) => sequence.HasMoreThan(count - 1);
public static bool HasMoreThan<T>(this IEnumerable<T> sequence, int count) => sequence.EnumerationCounterImpl(count, equals_vs_greaterThan: false);
public static bool HasExactly<T>(this IEnumerable<T> sequence, int count) => sequence.EnumerationCounterImpl(count, equals_vs_greaterThan: true);
public static bool EnumerationCounterImpl<T>(this IEnumerable<T> sequence, int count, bool equals_vs_greaterThan = true) //0
{
if (equals_vs_greaterThan && count < 0)
throw new ArgumentException($"{nameof(count)} is less than zero!");
if (!equals_vs_greaterThan && count < 0)
return true;
var staticCount = (sequence as ICollection)?.Count
?? (sequence as ICollection<T>)?.Count
?? (sequence as IReadOnlyCollection<T>)?.Count;
if (staticCount != null)
return staticCount > count;
using (var enumerator = sequence.GetEnumerator()) //1 optimization
{
for (int i = 0; i < count + 1; i++)
{
if (enumerator.MoveNext())
continue;
return false;
}
return !equals_vs_greaterThan // ==
|| enumerator.MoveNext(); // >
}
//0 https://blog.slaks.net/2015-01-12/linq-count-considered-occasionally-harmful/
//1 using the enumerator directly is slightly faster than using LINQ methods it avoids allocating an extra iterator
// state machine compared to using skip()
}
There! Problem solved again but this time around we are performance-conscious!

How about:
public bool IsValid
{
get { return (GetRuleViolations().Cast<RuleViolation>().Count() == 0); }
}

Related

Entity Framework Skip with Int64 parameter [duplicate]

How I can use long type (Int64) with Skip in Linq. It support only Int32.
dataContext.Persons.Skip(LongNumber);
You can use a while loop:
// Some init
List<Person> persons = new List<Person>();
List<Person> resultList = persons;
long bigNumber = 3 * (long)int.MaxValue + 12;
while (bigNumber > int.MaxValue)
{
resultList = resultList.Skip(int.MaxValue).ToList();
bigNumber -= int.MaxValue;
}
resultList = resultList.Skip(int.MaxValue).ToList();
// Then what do what you want with this result list
But does your collection have more than int.MaxValue entries?
The following extension method BigSkip allows skipping more than the Int32.MaxValue maximum value of LINQ's Skip method by calling the method multiple times until the long value has been reached. This method has the advantage of not causing iteration over the collection prematurely.
example usage
bigCollection.BigSkip(howMany: int.MaxValue + 1l)
method
using System;
using System.Collections.Generic;
using System.Linq;
static public class LinqExtensions
{
static public IEnumerable<T> BigSkip<T>(this IEnumerable<T> items, long howMany)
=> BigSkip(items, Int32.MaxValue, howMany);
internal static IEnumerable<T> BigSkip<T>(this IEnumerable<T> items, int segmentSize, long howMany)
{
long segmentCount = Math.DivRem(howMany, segmentSize,
out long remainder);
for (long i = 0; i < segmentCount; i += 1)
items = items.Skip(segmentSize);
if (remainder != 0)
items = items.Skip((int)remainder);
return items;
}
}
The method has been split into two: the internal overload is for convenience allowing a smaller segment size to be specified than Int32.MaxValue to make it unit testable on a smaller scale.
bonus
Replace Skip with Take to make a BigTake method; this same extension method pattern can be used to extend the reach of other LINQ methods.
Here is an implementation that includes a fast path, in case the count is in the Int32 range. In that case, any optimizations that are embedded in the native Skip implementation are enabled.
/// <summary>Bypasses a specified number of elements in a sequence and then
/// returns the remaining elements.</summary>
public static IEnumerable<T> LongSkip<T>(this IEnumerable<T> source, long count)
{
if (count >= 0 && count <= Int32.MaxValue)
return source.Skip(checked((int)count));
else
return Iterator(source, count);
static IEnumerable<T> Iterator(IEnumerable<T> source, long count)
{
long current = 0;
foreach (var item in source)
if (++current > count) yield return item;
}
}

Performance of Skip and Take in Linq to Objects

"Searching for alternative functionalities for "Skip" and "Take" functionalities"
1 of the link says "Everytime you invoke Skip() it will have to iterate you collection from the beginning in order to skip the number of elements you desire, which gives a loop within a loop (n2 behaviour)"
Conclusion: For large collections, don’t use Skip and Take. Find another way to iterate through your collection and divide it.
In order to access last page data in a huge collection, can you please suggest us a way other than Skip and Take approach?
Looking at the source for Skip, you can see it enumerates over all the items, even over the first n items you want to skip.
It's strange though, because several LINQ-methods have optimizations for collections, like Count and Last.
Skip apparently does not.
If you have an array or IList<T>, you use the indexer to truly skip over them:
for (int i = skipStartIndex; i < list.Count; i++) {
yield return list[i];
}
Internally it is really correct:
private static IEnumerable<TSource> SkipIterator<TSource>(IEnumerable<TSource> source, int count)
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (count > 0 && enumerator.MoveNext())
--count;
if (count <= 0)
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
}
If you want to skip for IEnumerable<T> then it works right. There are no other way except enumeration to get specific element(s). But you can write own extension method on IReadOnlyList<T> or IList<T> (if this interface is implemented in collection used for your elements).
public static class IReadOnlyListExtensions
{
public static IEnumerable<T> Skip<T>(this IReadOnlyList<T> collection, int count)
{
if (collection == null)
return null;
return ICollectionExtensions.YieldSkip(collection, count);
}
private static IEnumerable<T> YieldSkip<T>(IReadOnlyList<T> collection, int count)
{
for (int index = count; index < collection.Count; index++)
{
yield return collection[index];
}
}
}
In addition you can implement it for IEnumerable<T> but check inside for optimization:
if (collection is IReadOnlyList<T>)
{
// do optimized skip
}
Such solution is used a lot of where in Linq source code (but not in Skip unfortunately).
Depends on your implementation, but it would make sense to use indexed arrays for the purpose, instead.

Replace Linq methods in .NET 2.0

I've been looking everywhere for some examples on how could some methods used in LINQ be replaced with standard c# code. I have a very simple helper which I need to use in .NET 2.0 environment. I need an alternative for:
Skip()
Take()
using()
methods. I've seen this post, and seen LINQBridge solution, but was wondering if there is any resource that explains how to replace those methods with straight code alternative?
You could just write your own Take and Skip
public static IEnumerable<T> Skip<T>(IEnumerable<T> set, int count)
{
if(set == null) throw ArgumentNullException("set");
if(count < 0) throw ArgumentOutOfRangeException("count");
return SkipImp(set, count);
}
private static IEnumerable<T> SkipImp<T>(IEnumerable<T> set, int count)
{
foreach(var item in set)
{
if(count-- <= 0)
{
yield return item;
}
}
}
public static IEnumerable<T> Take<T>(IEnumerable<T> set, int count)
{
if(set == null) throw ArgumentNullException("set");
if(count < 0) throw ArgumentOutOfRangeException("count");
return TakeImp(set, count);
}
private static IEnumerable<T> TakeImp<T>(IEnumerable<T> set, int count)
{
foreach(var item in set)
{
if(count-- > 0)
{
yield return item;
}
else
{
yield break;
}
}
}
You'd have to do
var results = ContainingClass.Take(ContainingClass.Skip(list, 3), 4);
instead of
var results = list.Skip(3).Take(4);
Note the reason for two separate methods in each case is so the exceptions will be thrown when the method is called rather than when the IEnumerable<T> is iterated.
I think you can even make them extension methods if you use a compiler that supports that (VS 2008 and up), as it's a feature of the compiler version and not the .net version.

How use Long type for Skip in Linq

How I can use long type (Int64) with Skip in Linq. It support only Int32.
dataContext.Persons.Skip(LongNumber);
You can use a while loop:
// Some init
List<Person> persons = new List<Person>();
List<Person> resultList = persons;
long bigNumber = 3 * (long)int.MaxValue + 12;
while (bigNumber > int.MaxValue)
{
resultList = resultList.Skip(int.MaxValue).ToList();
bigNumber -= int.MaxValue;
}
resultList = resultList.Skip(int.MaxValue).ToList();
// Then what do what you want with this result list
But does your collection have more than int.MaxValue entries?
The following extension method BigSkip allows skipping more than the Int32.MaxValue maximum value of LINQ's Skip method by calling the method multiple times until the long value has been reached. This method has the advantage of not causing iteration over the collection prematurely.
example usage
bigCollection.BigSkip(howMany: int.MaxValue + 1l)
method
using System;
using System.Collections.Generic;
using System.Linq;
static public class LinqExtensions
{
static public IEnumerable<T> BigSkip<T>(this IEnumerable<T> items, long howMany)
=> BigSkip(items, Int32.MaxValue, howMany);
internal static IEnumerable<T> BigSkip<T>(this IEnumerable<T> items, int segmentSize, long howMany)
{
long segmentCount = Math.DivRem(howMany, segmentSize,
out long remainder);
for (long i = 0; i < segmentCount; i += 1)
items = items.Skip(segmentSize);
if (remainder != 0)
items = items.Skip((int)remainder);
return items;
}
}
The method has been split into two: the internal overload is for convenience allowing a smaller segment size to be specified than Int32.MaxValue to make it unit testable on a smaller scale.
bonus
Replace Skip with Take to make a BigTake method; this same extension method pattern can be used to extend the reach of other LINQ methods.
Here is an implementation that includes a fast path, in case the count is in the Int32 range. In that case, any optimizations that are embedded in the native Skip implementation are enabled.
/// <summary>Bypasses a specified number of elements in a sequence and then
/// returns the remaining elements.</summary>
public static IEnumerable<T> LongSkip<T>(this IEnumerable<T> source, long count)
{
if (count >= 0 && count <= Int32.MaxValue)
return source.Skip(checked((int)count));
else
return Iterator(source, count);
static IEnumerable<T> Iterator(IEnumerable<T> source, long count)
{
long current = 0;
foreach (var item in source)
if (++current > count) yield return item;
}
}

Filter an immutable list recursively

Let's say I have an array of integers, and I need to return an array of all the numbers that are divisible by 3 in order.
I'm given the interface:
List<int> ListElementsDivisibleBy3Recursive(List<int> input)
So it must take a list and return a list, and filter it recursively. I've tried popping elements out of the beginning of the list until I hit a number that matches the required condition, and that's where I get stuck. I don't know how to step to the next element and keep the element that matches the condition. This is what I have so far:
static List<int> ListElementsDivisibleBy3Recursive(List<int> input)
{
if (input.Count == 0)
return input;
else if (input.ElementAt(0) % 3 == 0)
{
return ListElementsDivisibleBy3Recursive(input); <--I have no idea what to do here
}
else
{
input.RemoveAt(0);
return ListElementsDivisibleBy3Recursive(input);
}
}
It would be much easier if I was allowed to pass a pointer to the position in the list I'm at, but all I have is the input list and the return list to work with. How do I delete elements in the list while keeping the ones that match the conditional? Or am I going about this all the wrong way? Not sure how I should be going about this logically. I also realize that my base condition is wrong too.
This is the only way I could see to do it. Every recursion removes the last element until the list is empty, and then when the recursion unwinds, the elements which satisfy the condition are added back to the end of the list.
List<int> ListElementsDivisibleBy3Recursive(List<int> input) {
if (input.Count > 0) {
int last = input.Last();
input.RemoveAt(input.Count - 1);
input = ListElementsDivisibleBy3Recursive(input);
if (last % 3 == 0)
input.Add(last);
}
return input;
}
Though it's pointless to return anything from the method, since input is modified as required regardless of the return value. So this achieves the same result:
void ListElementsDivisibleBy3Recursive(List<int> input) {
if (input.Count > 0) {
int last = input.Last();
input.RemoveAt(input.Count - 1);
ListElementsDivisibleBy3Recursive(input);
if (last % 3 == 0)
input.Add(last);
}
}
This whole problem is weird.
To solve the initial issue, of handling the current position, you could keep track of your current index (in a variable called count for my code), then do:
return currentList.AddRange(ListElementsDivisibleBy3Recursive(input.Skip(count).ToList()));
Using Skip to get rid of the already processed elements. Of course, at that point, you have LINQ, so you might as well do:
return currentList.AddRange(ListElementsDivisibleBy3Recursive(input.SkipWhile(i => i % 3 != 0).ToList()));
Granted, that one requires enumerating twice since you don't get the value out of SkipWhile. But you don't really need recursion at all, you could just write:
return currentList.Where( i => (i % 3) == 0).ToList();
If you really want to solve this problem by recursion, you can do it like this
static List<int> FilterMod3Internal(List<int> state, List<int> initialList, int index)
{
if (index >= initialList.Count())
{
return state;
}
else
{
var number = initialList[index];
if (number%3 == 0)
{
state.Add(number);
}
return FilterMod3Internal(state, initialList, index + 1);
}
}
static List<int> FilterMod3(List<int> list)
{
return FilterMod3Internal(new List<int>(), list, 0);
}
But as other answers noticed, this is a bad idea to do almost anything recursively, when it can be done with iteration (or at least tail recursion).
If you want to filter an existing collection without using more memory, you can do it like this
static void FilterListMod3Internal(List<int> list, int index)
{
if (index >= list.Count())
{
return;
}
var number = list[index];
if (number%3 != 0)
{
list.RemoveAt(index);
FilterListMod3Internal(list, index);
}
else
{
FilterListMod3Internal(list, index + 1);
}
}
Both versions are recursive, but they need to have some kind of internal function, that has additional parameters to maintain state between function calls.
You can also generalize this kind of methods like this
static List<T> FilterInternal<T>(List<T> state, List<T> initialList, int index, Func<T, bool> filterFunction)
{
if (index >= initialList.Count())
{
return state;
}
else
{
var item = initialList[index];
if (filterFunction(item))
{
state.Add(item);
}
return FilterInternal(state, initialList, index + 1, filterFunction);
}
}
static List<T> Filter<T>(List<T> list, Func<T, bool> filterFunction)
{
return FilterInternal<T>(new List<T>(), list, 0, filterFunction);
}
And the one that consumes no additional memory
static void FilterListInternal<T>(List<T> list, int index, Func<T, bool> filterFunction)
{
if (index >= list.Count())
{
return;
}
var item = list[index];
if (!filterFunction(item))
{
list.RemoveAt(index);
FilterListInternal(list, index, filterFunction);
}
else
{
FilterListInternal(list, index + 1, filterFunction);
}
}
static void FilterList<T>(List<T> list, Func<T, bool> filterFunction)
{
FilterListInternal<T>(list, 0, filterFunction);
}
where filterFunction should return true when you want the item to be in the resulting collection and true otherwise. It's easy to change, so, go try it, it you want.
Recursivly traversing a list to filter it is not a particularly appropriate algorithm for a mutable array-backed list. It's an approach that is more suited to dealing with immutable structures. When dealing with an immutable list (typically modeled as nodes with both a current item and a link to another node) a recursive solution is very well suited to this problem:
public class Node<T>
{
public Node(T value, Node<T> tail)
{
Value = value;
Tail = tail;
}
public T Value { get; private set; }
public Node<T> Tail { get; private set; }
}
public static Node<int> ListElementsDivisibleBy3Recursive(Node<int> node)
{
if (node == null)
return node;
else if (node.Value % 3 == 0)
return new Node<int>(node.Value, ListElementsDivisibleBy3Recursive(node.Tail));
else
return ListElementsDivisibleBy3Recursive(node.Tail);
}
We have a straightforward recursive case, where the node is null (the end of every list will have a Tail that is null). Then we have two recursive cases, either the current node's value matches the filter, and we create a new list with that node at the head and the tail being the recursive solution of the rest of the list, or the current node's value shouldn't be included and the solution is simply the recursion on the tail of the list.
A List<T> is simply not suited to this type of algorithm because it relies on being able to compute "a list with everything after the first item" as well as to also easily compute "a new list that is equal to the old list but with one item added to it", neither of which are operations that List<T> can perform easily or efficiently, but that immutable lists typically will have as primary operations.
Weird question :-)
This one is more flexible solution: extension method for IList RecursiveFilter accepts predicate and return IEnumerable (that can be used to construct List, Array or something else).
using System;
using System.Collections.Generic;
namespace Sandbox
{
class Program
{
static void Main()
{
var array = new[] { 1, 6, 8, 3, 6, 2, 9, 0, 7, 3, 5 };
var filtred = array.RecursiveFilter(i => i % 3 == 0);
foreach (var item in filtred)
Console.WriteLine(item);
}
}
public static class MyCollectionExtensions
{
public static IEnumerable<T> RecursiveFilter<T>(this IList<T> collection, Func<T, bool> predicate, int index = 0)
{
if (index < 0 || index >= collection.Count)
yield break;
if (predicate(collection[index]))
yield return collection[index];
foreach (var item in RecursiveFilter(collection, predicate, index + 1))
yield return item;
}
}
}
return input.Where( i => (i % 3) == 0).ToList();

Categories

Resources