Delete an element from a generic list - c#

I can´t remove an element from an IEnumerable list, but this list is a reference to a List , a private attribute of an other class.
If I put personsCollection.Remove(theElement) in the same class (class Manager), it works perfect, but I need to delete the element since the other class (class ManagerDelete). Please how can I do this?
Thanks.
class Other
{
//Some code
public IEnumerable<Person> SearchByPhone (string value)
{
return from person in personCollection
where person.SPhone == value
select person;
}
}
class ManagerDelete
{
//Some code
IEnumerable<Person> auxList= SearchByPhone (value);
//I have a method for delete here
}
class Manager
{
//Some code
private List<Person> personsCollection = new List<Person>();
}

You can't delete from an IEnumerable<T> you need to make it of type IList<T> to add/remove items directly from it.

You need to understand what an IEnumerable Interface allows you to do.
I'v listed below the list of Interfaces that you should use by design, as and when required in differnt circumstances. In your example IList is what you will need to use.
ICollection Defines general characteristics (e.g., size, enumeration,
and thread safety) for all non-generic collection types.
ICloneable Allows the implementing object to return a copy of itself
to the caller.
IDictionary Allows a non-generic collection object to represent its
contents using key/value pairs.
IEnumerable Returns an object implementing the IEnumerator interface
(see next table entry).
IEnumerator Enables foreach style iteration of collection items.
IList Provides behavior to add, remove, and index items in a
sequential list of objects.

Darren is right.
Without converting to a list you can do:
personCollection = personCollection.Except(SearchByPhone(value));
in ManagerDelete.

You can use ToList to convert the IEnumerable to a List and then you can remove stuff from it.
var auxList= SearchByPhone (value).ToList();
auxList.Remove(something);

You can cast the IEnumerable to an IList. This will work if the IEnumerable is really a List. However this is a bad design. If you want to remove items, you should expose the list as an IList, not IEnumerable.

An IEnumerable is literally just an interface to say, I've got this collection, you can iterate over it.
If you take a look at the actual details of the IEnumerable interface, it doesn't contain much, only a method to allow callers to iterate over it:
http://msdn.microsoft.com/en-gb/library/9eekhta0.aspx
The reason why List types can allow you to remove them, is it's built on top of the IEnumerable interface, giving you more functionality. It is supposed to represent a collection of objects you can manipulate. Whereas an IEnumerable is simply not designed to do this.
The Remove method actually stems from the underlying ICollection interface that List also implements:
http://msdn.microsoft.com/en-gb/library/bye7h94w.aspx

In addition to other answers: your data structure choice doesn't seem to be adequate. If you really plan to remove elements from a container, your container must not be an IEnumerable<> in the first place!
Consider the following choices:
switch from IEnumerable<> to ICollection<>;
replace removing with filtering out (.Where()) and obtaining a separate filtered IEnumerable<>.

Related

Generic collection mapping using reflection

If any class implements the IEnumerable interface at some stage in its hierarchy is it possible to to create a collection and populate that class?
I'm wanting to write a simple function that if it takes an object that implements either IList<>, ICollection<>, IEnumerable<> etc or is an Array (so all at some stage implements IEnumerable) that I can populate it with a collection of values.
So this function doesn't know if it will receive a List<object> or object[] but will be able to populate both.
Thanks.
The IEnumerable interface only specifies a method that gives you an enumerator to enumerate over the object’s items. As such there is no information about what the object’s other abilities is. So you cannot tell if the amount of items is fixed, or mutable or even mutable from the outside.
The first interface to supply this is IList which, in addition to the random access, provides methods to add objects. Just because you have an IList it does not mean you have write access to it though, as ILists can be read-only. There is also IDictionary which specifies add methods for dictionary-like objects. All other standard collections usually do not implement an interface that gives you this ability.
So, you cannot fill an arbitrary collection with values without knowing its implementation, or at least a more specific implementation detail (IList or IDictionary).
I don't need catch all functionality I just need something to cover most instances. So if IEnumerable, ICollection or IList are passed then I can just return a list.
If you get either an IList<T> or ICollection<T>, you also have an IEnumerable<T> (because both implement it), so you just have a single case. You can just accept an IEnumerable and create a list based on it:
public IList<T> CreateList<T> (IEnumerable<T> enumerable)
{
List<T> list = new List<T>(enumerable);
// add custom items
list.Add(GetCustomItem<T>());
return list;
}
If you like, you can also then make a version which is non-generic by just removing all the <T>s from the definition.

Why use ICollection and not IEnumerable or List<T> on many-many/one-many relationships?

I see this a lot in tutorials, with navigation properties as ICollection<T>.
Is this a mandatory requirement for Entity Framework? Can I use IEnumerable?
What's the main purpose of using ICollection instead of IEnumerable or even List<T>?
Usually what you choose will depend on which methods you need access to. In general - IEnumerable<> (MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx) for a list of objects that only needs to be iterated through, ICollection<> (MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx) for a list of objects that needs to be iterated through and modified, List<> for a list of objects that needs to be iterated through, modified, sorted, etc (See here for a full list: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).
From a more specific standpoint, lazy loading comes in to play with choosing the type. By default, navigation properties in Entity Framework come with change tracking and are proxies. In order for the dynamic proxy to be created as a navigation property, the virtual type must implement ICollection.
A navigation property that represents the "many" end of a relationship must return a type that implements ICollection, where T is the type of the object at the other end of the relationship. -Requirements for Creating POCO ProxiesMSDN
More information on Defining and Managing RelationshipsMSDN
ICollection<T> is used because the IEnumerable<T> interface provides no way of adding items, removing items, or otherwise modifying the collection.
Responding to your question about List<T>:
List<T> is a class; specifying an interface allows more flexibility of implementation. A better question is "why not IList<T>?"
To answer that question, consider what IList<T> adds to ICollection<T>: integer indexing, which means the items have some arbitrary order, and can be retrieved by reference to that order. This is probably not meaningful in most cases, since items probably need to be ordered differently in different contexts.
There are some basics difference between ICollection and IEnumerable
IEnumerable - contains only GetEnumerator method to get Enumerator and allows looping
ICollection contains additional methods: Add, Remove, Contains, Count, CopyTo
ICollection is inherited from IEnumerable
With ICollection you can modify the collection by using the methods like add/remove. You don't have the liberty to do the same with IEnumerable.
Simple Program:
using System;
using System.Collections;
using System.Collections.Generic;
namespace StackDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person("John",30));
persons.Add(new Person("Jack", 27));
ICollection<Person> personCollection = persons;
IEnumerable<Person> personEnumeration = persons;
// IEnumeration
// IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
foreach (Person p in personEnumeration)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
// ICollection
// ICollection Add/Remove/Contains/Count/CopyTo
// ICollection is inherited from IEnumerable
personCollection.Add(new Person("Tim", 10));
foreach (Person p in personCollection)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
Console.ReadLine();
}
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
}
I remember it this way:
IEnumerable has one method GetEnumerator() which allows one to read through the values in a collection but not write to it. Most of the complexity of using the enumerator is taken care of for us by the for each statement in C#. IEnumerable has one property: Current, which returns the current element.
ICollection implements IEnumerable and adds few additional properties the most use of which is Count. The generic version of ICollection implements the Add() and Remove() methods.
IList implements both IEnumerable and ICollection, and add the integer indexing access to items (which is not usually required, as ordering is done in database).
The basic idea of using ICollection is a provide an interface to readonly-access to some finite amount of data. In fact you have a ICollection.Count property. IEnumerable is more suitable for some chain of the data where you read till some logical point, some condition esplicitly specified by consumer or till the end of the enumeration.
Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading.
If a navigation property can hold multiple entities (as in many-to-many or one-to-many relationships), its type must be a list in which entries can be added, deleted, and updated, such as ICollection.
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
What I have done in the past is declare my inner class collections using IList<Class>, ICollection<Class>or IEnumerable<Class> (if static list) depending on whether or not I will have to do any number of the following in a method in my repository: enumerate, sort/order or modify. When I just need to enumerate (and maybe sort) over objects then I create a temp List<Class>to work with the collection within an IEnumerable method. I think this practice would only be effective if the collection is relatively small, but it may be good practice in general, idk. Please correct me if there is evidence as to why this would not good practice.
Lets try thinking outside of the box with/by logic and understand clearly these three interfaces in your question:
When the class of some instance implements the System.Collection.IEnumerable interface then, in simple words, we can say that this instance is both enumerable and iterable, which means that this instance allows somehow in a single loop to go/get/pass/traverse/iterate over/through all the items and elements that this instance contains.
This means that this is also possible to enumerate all the items and elements that this instance contains.
Every class that implements the System.Collection.IEnumerable interface also implements the GetEnumerator method that takes no arguments and returns an System.Collections.IEnumerator instance.
Instances of System.Collections.IEnumerator interface behaves very similar to C++ iterators.
When the class of some instance implements the System.Collection.ICollection interface then, in simple words, we can say that this instance is some collection of things.
The generic version of this interface, i.e. System.Collection.Generic.ICollection, is more informative because this generic interface explicitly states what is the type of the things in the collection.
This is all reasonable, rational, logical and makes sense that System.Collections.ICollection interface inherits from System.Collections.IEnumerable interface, because theoretically every collection is also both enumerable and iterable and this is theoretically possible to go over all the items and elements in every collection.
System.Collections.ICollection interface represents a finite dynamic collection that are changeable, which means that exist items can be removed from the collection and new items can be added to the same collection.
This explains why System.Collections.ICollection interface has the "Add" and "Remove" methods.
Because that instances of System.Collections.ICollection interface are finite collections then the word "finite" implies that every collection of this interface always has a finite number of items and elements in it.
The property Count of System.Collections.ICollection interface supposes to return this number.
System.Collections.IEnumerable interface does not have these methods and properties that System.Collections.ICollection interface has, because it does not make any sense that System.Collections.IEnumerable will have these methods and properties that System.Collections.ICollection interface has.
The logic also says that every instance that is both enumerable and iterable is not necessarily
a collection and not necessarily changeable.
When I say changeable, I mean that don't immediately think that you can add or remove something from something that is both enumerable and iterable.
If I just created some finite sequence of prime numbers, for example, this finite sequence of prime numbers is indeed an instance of System.Collections.IEnumerable interface, because now I can go over all the prime numbers in this finite sequence in a single loop and do whatever I want to do with each of them, like printing each of them to the console window or screen, but this finite sequence of prime numbers is not an instance of System.Collections.ICollection interface, because this is not making sense to add composite numbers to this finite sequence of prime numbers.
Also you want in the next iteration to get the next closest larger prime number to the current prime number in the current iteration, if so you also don't want to remove exist prime numbers from this finite sequence of prime numbers.
Also you probably want to use, code and write "yield return" in the GetEnumerator method of the System.Collections.IEnumerable interface to produce the prime numbers and not allocating anything on the memory heap and then task the Garbage Collector (GC) to both deallocate and free this memory from the heap, because this is obviously both waste of operating system memory and decreases performance.
Dynamic memory allocation and deallocation on the heap should be done when invoking the methods and properties of System.Collections.ICollection interface, but not when invoking the methods and properties of System.Collections.IEnumerable interface (although System.Collections.IEnumerable interface has only 1 method and 0 properties).
According to what others said in this Stack Overflow webpage, System.Collections.IList interface simply represents an orderable collection and this explains why the methods of System.Collections.IList interface work with indexes in contrast to these of System.Collections.ICollection interface.
In short System.Collections.ICollection interface does not imply that an instance of it is orderable, but System.Collections.IList interface does imply that.
Theoretically ordered set is special case of unordered set.
This also makes sense and explains why System.Collections.IList interface inherits System.Collections.ICollection interface.

When should you use IEnumerable and GetEnumerator?

In many of our projects I have seen a few custom collection / or container classes that hold a some sort of generic collection, e.g. a List(of T) class.
They usually have a GetXXX method that returns a IEnumerable of whatever type the custom collection class uses so the internal collection can be iterated around using a foreach loop.
e.g.
public IEnumerable<UploadState> GetStates
{
get
{
return new List<UploadState>(m_states);
}
}
My question is that should these classes instead implement the IEnumerable interface, and call GetEnumerator on the List itself.
Is there a preferred way, or is it up to the developer?
If your class is a custom collection class then yes, it should implement IEnumerable<T>. In this case a public property for the inner list would be redundant. Imagine a simple class:
public class People : IEnumerable<Person>
{
List<Person> persons = new List<Person>();
public IEnumerator<Person> GetEnumerator()
{
return persons.GetEnumerator();
}
}
But if your class cannot act like a collection then provide a public IEnumerable property for its elements:
public class Flight
{
List<Person> passengers = new List<Person>();
public IEnumerable<Person> Passengers
{
get { return passengers; }
}
}
Anyway, it's always up to the developer to choose the right design.
I would do it that way:
public IEnumerable<UploadState> GetStates
{
get
{
foreach (var state in m_states) {
yield return state;
}
}
}
It is cleaner, your users don't get a list where they shouldn't (they could cast it to a List<T>after all) and you don't need to create a List<T>object.
EDIT: Misunderstood the question. I think if the class is meant to be a collection, it should implement IEnumerable<T>.
Consider that in your code example a new list created. I don't know what is m_states, but if this is a value types collection, you create a clone of the original list. In this way the returning list can be manipulated form the caller Add/Remove/Update elements. without affectiing original data.
If m_states are reference types, this still creates a new list which can be again manipulated by the caller Add/Remove/ No update elements (it's a reference!) without affecting original data.
What about IEnumerable<T>, its just a way to make a returning type generic, and not make strong coupling to List<T> type.
I think if your newly implemented class just behaves the sameway as a list does, there is no need to implement it. If you need some kind of custom logic, it depends on what you want to do; you can inherit list or you can implement IEnumerable. It just depends what is to be achieved.
You might want to check this:
http://www.codeproject.com/Articles/4074/Using-IEnumerator-and-IEnumerable-in-the-NET-Frame
I didn't read fully it yet, but I think this answers your question.
You should be deriving your custom collection classes based on one of the classes in System.Collections.ObjectModel namespace. They already contain implementations of IEnumerable<T> and the non generic IEnumerable interfaces.

How do I convert IEnumerable to a custom type in C#?

I am using extension methods OrderBy and ThenBy to sort my custom collection on multiple fields. This sort does not effect the collection but instead returns and IEnumberable. I am unable to cast the IEnumerable result to my custom collection. Is there anyway to change the order of my collection or convert the IEnumerable result to my custom collection?
If your collection type implements IList<T> (to be able to Add() to it) you could write an extension method:
public static Extensions
{
public static TColl ToTypedCollection<TColl, T>(this IEnumerable ien)
where TColl : IList<T>, new()
{
TColl collection = new TColl();
foreach (var item in ien)
{
collection.Add((T) item);
}
return collection;
}
}
No there isn't. When you use the query operators, it doesn't use instances of the original collection to generate the enumeration. Rather, it uses private implementations (possibly anonymous, possibly not) to provide this functionality.
If you want it in your original collection, you should have a constructor on the type which takes an IEnumerable<T> (or whatever your collection stores, if it is specific) and then pass the query to the constructor.
You can then use this to create an extension method for IEnumerable<T> called To<YourCollectionType> which would take the IEnumerable<T> and then pass it to the constructor of your type and return that.
No. You could follow the pattern established by the ToList and ToDictionary extension methods - write a similar extension method to load up your own collection type from IEnumerable.
You could write your own instance of IComparer to be able to sort your custom collect.
Brute force you could loop through the IEnumerable and dump each item back into a new instance of your custom collection.
You can initialize a list with IEnumerable:
If items is of type IEnumerable, you can create a list like this:
var list = new List<string>(items);
or you could simply call items.ToList():
var list = items.ToList();
What interfaces does your custom collection implement?
If its an IList then you'd be able to do .ToList() on the IEnumerable
If its an IDictionary then you'd be able to do .ToDictionary() on the IEnumerable
Etc..
to bring it to something more workable for you.
You could write an extension method for IEnumerable to .ToMyCollection() if nothing is similar.
Enumerables and collections are fairly different beasts.
Enumerations only allow to, well, enumerate while collections have index-based accessors, Count-property and the like. To create a collection you will actually have to enumerate the IEnumerable. Typical Collections like List<T> will have a constructor that accept an IEnumerable. Nonetheless, the enumeration will be performed.
If you look in the System.Linq.Enumerable class there are a few extension methods that will aloow you to convert you IEnumerable type to either an Array, ToList
var myEnumerable = this.GetEnumerator();
var array = myEnumerable.ToArray();
var list myEnumerable.ToList();
You could follow this approach and create a custom extension method that will convert to your custom collection
public static CustomCollection<TSource> ToCustomCollection<TSource>(this IEnumerable<TSource> source);
LINQ is cool because it treats the source-collections like this as immutable - it is not modifying them. Using the extension methods simply enumerates them in the alternate order you specify - you are not building a NEW custom list in this way.
I would suggest two options:
Build a new list yourself based on the results of your LINQ-ing
Implement sorting capability into your custom collection (or use a nice sortable generic collection as a base) so it can sort in-place.
Do you really need a custom collection type at all? It sounds like everything you want to do with this is provided by the existing generic collection types, and maybe you just need to add an extension method or to for them.

When to use IList and when to use List

I know that IList is the interface and List is the concrete type but I still don't know when to use each one. What I'm doing now is if I don't need the Sort or FindAll methods I use the interface. Am I right? Is there a better way to decide when to use the interface or the concrete type?
There are two rules I follow:
Accept the most basic type that will work
Return the richest type your user will need
So when writing a function or method that takes a collection, write it not to take a List, but an IList<T>, an ICollection<T>, or IEnumerable<T>. The generic interfaces will still work even for heterogenous lists because System.Object can be a T too. Doing this will save you headache if you decide to use a Stack or some other data structure further down the road. If all you need to do in the function is foreach through it, IEnumerable<T> is really all you should be asking for.
On the other hand, when returning an object out of a function, you want to give the user the richest possible set of operations without them having to cast around. So in that case, if it's a List<T> internally, return a copy as a List<T>.
Microsoft guidelines as checked by FxCop discourage use of List<T> in public APIs - prefer IList<T>.
Incidentally, I now almost always declare one-dimensional arrays as IList<T>, which means I can consistently use the IList<T>.Count property rather than Array.Length. For example:
public interface IMyApi
{
IList<int> GetReadOnlyValues();
}
public class MyApiImplementation : IMyApi
{
public IList<int> GetReadOnlyValues()
{
List<int> myList = new List<int>();
... populate list
return myList.AsReadOnly();
}
}
public class MyMockApiImplementationForUnitTests : IMyApi
{
public IList<int> GetReadOnlyValues()
{
IList<int> testValues = new int[] { 1, 2, 3 };
return testValues;
}
}
IEnumerable
You should try and use the least specific type that suits your purpose.
IEnumerable is less specific than IList.
You use IEnumerable when you want to loop through the items in a collection.
IList
IList implements IEnumerable.
You should use IList when you need access by index to your collection, add and delete elements, etc...
List
List implements IList.
There's an important thing that people always seem to overlook:
You can pass a plain array to something which accepts an IList<T> parameter, and then you can call IList.Add() and will receive a runtime exception:
Unhandled Exception: System.NotSupportedException: Collection was of a fixed size.
For example, consider the following code:
private void test(IList<int> list)
{
list.Add(1);
}
If you call that as follows, you will get a runtime exception:
int[] array = new int[0];
test(array);
This happens because using plain arrays with IList<T> violates the Liskov substitution principle.
For this reason, if you are calling IList<T>.Add() you may want to consider requiring a List<T> instead of an IList<T>.
I would agree with Lee's advice for taking parameters, but not returning.
If you specify your methods to return an interface that means you are free to change the exact implementation later on without the consuming method ever knowing. I thought I'd never need to change from a List<T> but had to later change to use a custom list library for the extra functionality it provided. Because I'd only returned an IList<T> none of the people that used the library had to change their code.
Of course that only need apply to methods that are externally visible (i.e. public methods). I personally use interfaces even in internal code, but as you are able to change all the code yourself if you make breaking changes it's not strictly necessary.
It's always best to use the lowest base type possible. This gives the implementer of your interface, or consumer of your method, the opportunity to use whatever they like behind the scenes.
For collections you should aim to use IEnumerable where possible. This gives the most flexibility but is not always suited.
If you're working within a single method (or even in a single class or assembly in some cases) and no one outside is going to see what you're doing, use the fullness of a List. But if you're interacting with outside code, like when you're returning a list from a method, then you only want to declare the interface without necessarily tying yourself to a specific implementation, especially if you have no control over who compiles against your code afterward. If you started with a concrete type and you decided to change to another one, even if it uses the same interface, you're going to break someone else's code unless you started off with an interface or abstract base type.
You are most often better of using the most general usable type, in this case the IList or even better the IEnumerable interface, so that you can switch the implementation conveniently at a later time.
However, in .NET 2.0, there is an annoying thing - IList does not have a Sort() method. You can use a supplied adapter instead:
ArrayList.Adapter(list).Sort()
I don't think there are hard and fast rules for this type of thing, but I usually go by the guideline of using the lightest possible way until absolutely necessary.
For example, let's say you have a Person class and a Group class. A Group instance has many people, so a List here would make sense. When I declare the list object in Group I will use an IList<Person> and instantiate it as a List.
public class Group {
private IList<Person> people;
public Group() {
this.people = new List<Person>();
}
}
And, if you don't even need everything in IList you can always use IEnumerable too. With modern compilers and processors, I don't think there is really any speed difference, so this is more just a matter of style.
You should use the interface only if you need it, e.g., if your list is casted to an IList implementation other than List. This is true when, for example, you use NHibernate, which casts ILists into an NHibernate bag object when retrieving data.
If List is the only implementation that you will ever use for a certain collection, feel free to declare it as a concrete List implementation.
In situations I usually come across, I rarely use IList directly.
Usually I just use it as an argument to a method
void ProcessArrayData(IList almostAnyTypeOfArray)
{
// Do some stuff with the IList array
}
This will allow me to do generic processing on almost any array in the .NET framework, unless it uses IEnumerable and not IList, which happens sometimes.
It really comes down to the kind of functionality you need. I'd suggest using the List class in most cases. IList is best for when you need to make a custom array that could have some very specific rules that you'd like to encapsulate within a collection so you don't repeat yourself, but still want .NET to recognize it as a list.
A List object allows you to create a list, add things to it, remove it, update it, index into it and etc. List is used whenever you just want a generic list where you specify object type in it and that's it.
IList on the other hand is an Interface. Basically, if you want to create your own custom List, say a list class called BookList, then you can use the Interface to give you basic methods and structure to your new class. IList is for when you want to create your own, special sub-class that implements List.
Another difference is:
IList is an Interface and cannot be instantiated. List is a class and can be instantiated. It means:
IList<string> list1 = new IList<string>(); // this is wrong, and won't compile
IList<string> list2 = new List<string>(); // this will compile
List<string> list3 = new List<string>(); // this will compile

Categories

Resources