Related
I'm trying to get the most specific interface that both types implement. Getting the list of interfaces is fairly easy:
var interfaces = leftType.GetInterfaces().Intersect(rightType.GetInterfaces());
Then, I traverse the list and remove interfaces that are "included" into other interfaces:
var remaining = interfaces.ToDictionary(i => i, i => true);
foreach(var iface in interfaces)
foreach(var subIface in iface.GetInterfaces())
remaining.Remove(subIface);
However, when trying to get the most common interface for int[] and List<int>, I get a list of three interfaces:
IList (non-generic)
IList<int>
IReadOnlyList<int>
First of all, why doesn't IList<T> implement non-generic IList, while IEnumerable<T> does actually implement IEnumerable?
Then, the IReadOnlyList causes a certain confusion. The name implies that the container that implements the interface prohibits modification, but the usage, on the contrary, implies that the container allows read access and doesn't care about modifications. But if so, why doesn't IList<T> implement IReadOnlyList<T>?
Maybe the whole approach is incorrect, and there's a more clever way to detect the most specific interface?
IList<T> doesn't implement IList because IList<T> allows you to pass objects in. Allowing the usage of a non-generic interface here would break type safety.
Imagine this:
IList list = new List<WhateverClass>();
list.Add(new object()); // Runtime error because the type doesn't match
IEnumerable<T> only allows you to get objects out though, not pass them in (T is covariant). You can iterate over the elements of an IEnumerable<T> and treat all items like objects. So IEnumerable<T> can implement IEnumerable without problems.
Also, the fact that List<T> implements IReadOnlyList<T> just implies that List<T> fulfills the contract required by the interface (which doesn't explicitly prohibit being actually modifiable).
If you just need read access to a list, you can treat a List<T> like a readonly list.
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<>.
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.
While I do a program, sometimes I've got this doubt. I have been using List<T> but I haven't used the others.
I'd like to know when each one is better to use, and under what circumstances.
I'm sure you can read the documentation by yourself. I'll give a short summary here:
IEnumerable is an interface that exposes an enumerator over a collection. Implement this interface if want to be able to support iteration, for example inside a foreach loop.
Collection is an implementation of IEnumerable (therefore you can iterate over it) that is generally further extended by user-defined classes that want to have collection-like behavior (i.e. use Add, Remove, Contains, etc.). It can also be used "as-is".
List is also an implementation of IEnumerable (therefore you can iterate over it) that is generally used "as-is" as a container for objects of a certain type. Uses a dynamically adjusting array in the background and is the generic equivalent of ArrayList.
Note that while IEnumerable can be both generic and non-generic, Collection and List can only be used as generic classes.
List is instantiable type that holds items in a linear fashion. (Edit: I'm told it's implemented with a dynamic array, rather than with a Linked List, which was just my guess).
ICollection/CollectionBase and IEnumerable aren't directly instantiable types.
CollectionBase/ICollection is a base class/interface that is inherited/implemented by any class that considers itself a collection and holds multiple items. CollectionBase/ICollection also allows you to pass around collections without knowing their implementation.
IEnumerableis also a interface that provides methods for iterating over the collection. IEnumerable basically lets you use foreach loops on the collection. You can use the interface methods directly to get some C++ style iterators going, but the foreach loop is less error prone.
MSDN can:
List<T>
IList<T>
ICollection<T>
IEnumerable<T>
If you look at the definitions of the three (see below) you will notice that List implements Enumerable and ICollection and ICollection implements IEnumerable. More clearly:
List is CLASS which can store a variable number of items of the same type plus the functionality specified by the other two interfaces.
ICollection is an interface which specifies a generic way to manipulate collections. NOTE: this is an interface and thus is NOT capable of being instantiated.
IEnumerable is an interface which specifies a means of iterating over a collection. NOTE: this is an interface and thus is NOT capable of being instantiated.
List
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IList, ICollection, IEnumerable
ICollection
Defines methods to manipulate generic collections.
public interface ICollection<T> : IEnumerable<T>,
IEnumerable
IEnumerable
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
public interface IEnumerable<out T> : IEnumerable
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