Casting an Object into the Same Type as an Ienumerable Collection

Cast object to IEnumerable<object>?

It's hard to answer this without a concrete use-case, but you may find it sufficient to simply cast to the non-generic IEnumerable interface.

There are two reasons why this will normally work for most types that are considered "sequences".

  1. The "classic" .NET 1.x collection classes implement IEnumerable.
  2. The generic IEnumerable<T> interface inherits from IEnumerable, so the cast should work fine for the generic collection classes in System.Collections.Generic, LINQ sequences etc.

EDIT:

As for why your provided sample doesn't work:

  1. This wouldn't work in C# 3 because it doesn't support generic interface covariance - you can't view an IEnumerable<Derived> as an IEnumerable<Base>.
  2. This wouldn't work in C# 4 either despite the fact that IEnumerable<T> is covariant, since variance is not supported for value-types - the cast from int[] (an IEnumerable<int>) --> IEnumerable<object> can't succeed.

Cast received object to a List<object> or IEnumerable<object>

C# 4 will have covariant and contravariant template parameters, but until then you have to do something nongeneric like

IList collection = (IList)myObject;

In C# can you up-cast an object type to a collection type of generic "object"s

As long chain of comments under your question shows - you cannot cast HashSet<Availability> to HashSet<object>, because there is just no implicit\explicit\any other conversion defined between those two types. However, HashSet<T> implements several covariant interfaces, such as IReadOnlyCollection<T> and IEnumerable<T>, and you can cast HashSet<Availability> to those interfaces (of object):

object myObject = getMyObject();
var myUsefulObject = (IReadOnlyCollection<object>)myObject;

If type T is covariant in interface - this type cannot be used as argument in any method in that interface and can only be used as return type. That means all methods which might break type-safety in this case (such as Add(T item), Remove(T item) and so on) cannot be present in such interface, and returning Availability as object is not a problem.

How to convert Array of objects into an IEnumerable of inheriting object?

You can use LINQ to cast the objects of the enumeration to a different related type.

pInfo.Cast<PInfo3>();

Now, this can cause some issues if there are some elements in the collection that can't be cast, but there are ways around that as well (see Edit):

pInfo.Select(p => (PInfo3)p).Where(p => p != null);

The Cast should be used when you know that the conversion will succeed, and the second when there could be elements that can't make the conversion.

EDIT

Per Daniel A. White's comment below, there is also the .OfType<T>() method, which will only get the items that match the requested type, and avoid the IllegalCastException that Cast<T>() will throw.

For additional details, see this answer.

Passing IEnumerable<Object> to MVC view and casting to strongly typed object

Initially, you could use Cast on the entire collection:

foreach (var item in Model.Items.Cast<MyCustomObject>()){}

If your types will all inherit from a base type, say MyCustomObject, then your model should specify this, e.g.

public class MyViewModel<T> where T : MyCustomObject, new() 
{
public IEnumerable<T> Items { get; set; }
}

You would need to ensure that any types you wished to add to your items collection inherited from the base MyCustomObject type

Casting an object to IEnumerable<T> where T is not known

Well, since you don't know the actual type of the items until runtime, you don't need to use the generic IEnumerable<T> interface; just use the non-generic one, IEnumerable (the generic one inherits from it):

private void WriteGenericCollection(object obj)
{
IEnumerable enumerable = (IEnumerable)obj;
foreach(object item in enumerable)
{
...
}
}


Related Topics



Leave a reply



Submit