90

Assume you have a basic Employee class as such:

class Employee
{
   public string Name;
   public int Years;
   public string Department;
}

Then (in a seperate class) I have the following code fragments (I think i understand all but the last):

I believe that the following code fragment works because the array initiliser creates an array of Employee objects which are the same type as the workforce variable being assigned to.

Employee[] workforceOne = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

I then have the following code fragment. I believe this works because the array of Employee objects implicity is an implementation of the Array() class which implements IEnumerable. Therefore, I believe this is why the array can be assigned to IEnumerable?

IEnumerable workforceTwo = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

Then I have this code fragment:

IEnumerable<Employee> workforceThree = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

I am not sure why this code fragment works? IEnumerable<Employee> inherits from IEnumerable (and overrides (or overloads?) the GetEnumerator() method) but shouldn't i therefore need a cast for the above to work as such:

//The cast does work but is not required
IEnumerable<Employee> workforceFour = (IEnumerable<Employee>)new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

It seems that the array is being implicitly down cast from a type of IEnumerable to IEnumerable<Employee> but I always thought when you needed to convert a type to something more specific you needed an explicit cast.

Maybe i'm missing something simple in my understanding here but can someone please help me with my understanding around this.

Thank you.

1
  • 3
    @Aliostad: It's right below the workforceThree fragment. Commented Aug 24, 2011 at 9:39

3 Answers 3

123

From the documentation:

In the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools. As a result, the generic interfaces do not appear in the declaration syntax for the Array class, and there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations).

Thus, your Employee[] implements IEnumerable<Employee>.

Sign up to request clarification or add additional context in comments.

1 Comment

To clarify, it is not the Array class that implements it, it's T[] of any T.
7

The Array of Employees by default implements IEnumerable<Employee> as well as IEnumerable

Comments

3

Explicit cast is needed when some sentence needs to be downcasted. That's casting an object to a more specialized type - if the object is of such specialized type -.

In the other hand, upcasting (casting to a less specialized type), will never need an explicit cast, but you can explicitly do it (it's just useless).

Since Array implements IEnumerable and IEnumerable<T>, you're doing an upcast in your code, meaning _you don't need to explicitly cast to IEnumerable<T>.

3 Comments

I'm not agree. In some case you need an explicit upcast. As an example function override : void DoStuffs(IEnumerable<T> objects) { ... } void DoStuffs(params T[] objects) { DoStuffs((IEnumerable<T>) objects); }
@Orace This isn't exactly an upcast... It's a compiler help to let it invoke the desired overload... are you agree? ;) It's a method overload resolution issue.
@Orace Well, it's an upcast, but I mean that you need the explicit "cast" to invoke the desired overload...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.