The ``++foreach++`` statement was introduced in the C# language prior to generics to make it easier to work with the non-generic collections available at that time such as ``++ArrayList++``. The ``++foreach++`` statements allows you to downcast elements of a collection of ``++Object++``s to any other type. The problem is that to achieve the cast, the ``++foreach++`` statements silently performs ``++explicit++`` type conversion, which at runtime can result in an ``++InvalidCastException++``.


C# code iterating on generic collections or arrays should not rely on ``++foreach++`` statement's silent ``++explicit++`` conversions.


== Noncompliant Code Example

[source,csharp]
----
public class Fruit { }
public class Orange : Fruit { }
public class Apple : Fruit { }

class MyTest
{
  public void Test()
  {
    var fruitBasket = new List<Fruit>();
    fruitBasket.Add(new Orange());
    fruitBasket.Add(new Orange());
    // fruitBasket.Add(new Apple());  // uncommenting this line will make both foreach below throw an InvalidCastException

    foreach (Fruit fruit in fruitBasket) 
    {
      var orange = (Orange)fruit; // This "explicit" conversion is hidden within the foreach loop below
      ...
    }

    foreach (Orange orange in fruitBasket) // Noncompliant
    {
      ...
    } 
  }
}
----


== Compliant Solution

[source,csharp]
----
var fruitBasket = new List<Orange>();
fruitBasket.Add(new Orange());
fruitBasket.Add(new Orange());
// fruitBasket.Add(new Apple());  // uncommenting this line won't compile

foreach (Orange orange in fruitBasket)
{
  ...
} 
----

or


[source,csharp]
----
var fruitBasket = new List<Fruit>();
fruitBasket.Add(new Orange());
fruitBasket.Add(new Orange());
fruitBasket.Add(new Apple());

foreach (Orange orange in fruitBasket.OfType<Orange>())
{
  ...
} 
----


== Exceptions

The rule ignores iterations on collections of ``++object++``s. This includes legacy code that uses ``++ArrayList++``. Furthermore, the rule does not report on cases when user defined conversions are being called. 


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::message.adoc[]

'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
