C# 将收到的对象强制转换为列表<;对象>;或IEnumerable<;对象>;

C# 将收到的对象强制转换为列表<;对象>;或IEnumerable<;对象>;,c#,.net,C#,.net,我正在尝试执行以下演员阵容 private void MyMethod(object myObject) { if(myObject is IEnumerable) { List<object> collection = (List<object>)myObject; ... do something } else { ... do something

我正在尝试执行以下演员阵容

private void MyMethod(object myObject)  
{  
    if(myObject is IEnumerable)  
    {
        List<object> collection = (List<object>)myObject;  
        ... do something   
    }  
    else  
    {  
        ... do something  
    }  
}
private void MyMethod(object myObject)
{  
if(myObject是IEnumerable)
{
列表集合=(列表)myObject;
…做点什么
}  
其他的
{  
…做点什么
}  
}
但我总是有以下例外:

无法将类型为“System.Collections.Generic.List
1[MySpecificType]”的对象强制转换为类型为“System.Collections.Generic.List
1[System.object]”

我确实需要这样做,因为这个方法需要非常通用,才能接收单一对象和未指定类型的集合

这是可能的,还是有另一种方法可以做到这一点

谢谢。

怎么样

List<object> collection = new List<object>((IEnumerable)myObject);
List集合=新列表((IEnumerable)myObject);

您不能将IEnumerable强制转换为列表

但您可以使用LINQ实现这一点:

var result = ((IEnumerable)myObject).Cast<object>().ToList();
var result=((IEnumerable)myObject.Cast().ToList();
C#4将具有协变和逆变模板参数,但在此之前,您必须执行一些非通用的操作,如

IList collection = (IList)myObject;

你真的需要比普通
IEnumerable
提供的更多的信息吗?只需将其转换为该值,并使用
foreach
即可。我在一些协议缓冲区中遇到了完全相同的情况,我发现转换到
IEnumerable
(或
IList
以像列表一样访问它)效果非常好。

问题是,您试图向上转换到更丰富的对象。您只需将项目添加到新列表:

if (myObject is IEnumerable)
{
   List<object> list = new List<object>();
   var enumerator = ((IEnumerable) myObject).GetEnumerator();
   while (enumerator.MoveNext())
   {
      list.Add(enumerator.Current);
   }
}
if(myObject是IEnumerable)
{
列表=新列表();
变量枚举器=((IEnumerable)myObject).GetEnumerator();
while(枚举数.MoveNext())
{
list.Add(枚举数.Current);
}
}

这个代码对我很有用

List<Object> collection = new List<Object>((IEnumerable<Object>)myObject);
List集合=新列表((IEnumerable)myObject);

必须加入乐趣

    private void TestBench()
    {
        // An object to test
        string[] stringEnumerable = new string[] { "Easy", "as", "Pi" };

        ObjectListFromUnknown(stringEnumerable);
    }

    private void ObjectListFromUnknown(object o)
    {
        if (typeof(IEnumerable<object>).IsAssignableFrom(o.GetType()))
        {
            List<object> listO = ((IEnumerable<object>)o).ToList();
            // Test it
            foreach (var v in listO)
            {
                Console.WriteLine(v);
            }
        }
    }
private void TestBench()
{
//测试对象
字符串[]stringEnumerable=新字符串[]{“Easy”、“as”、“Pi”};
ObjectListFromUnknown(stringEnumerable);
}
私有void ObjectListFromUnknown(对象o)
{
if(typeof(IEnumerable).IsAssignableFrom(o.GetType())
{
List listO=((IEnumerable)o.ToList();
//测试一下
foreach(列表中的变量v)
{
控制台写入线(v);
}
}
}

您需要像这样使用as操作符键入cast

private void MyMethod(object myObject)  
{  
if(myObject is IEnumerable)  
{
    List<object> collection = myObject as(List<object>); 
    ... do something   
}  
else  
{  
    ... do something  
}  
}      
private void MyMethod(object myObject)
{  
if(myObject是IEnumerable)
{
列表集合=myObject as(列表);
…做点什么
}  
其他的
{  
…做点什么
}  
}      
如今它就像:

var collection = new List<object>(objectVar);
var集合=新列表(objectVar);

这也创建了一个新列表,而不是强制转换原始列表。我不得不使用
(IEnumerable)
而不仅仅是
(IEnumerable)
,但在其他方面效果很好。我使用了dotnetcore 3。0@Sergio,如果希望避免运行时错误的风险,则应在强制转换之前检查myObject是否实现了IList而不是IEnumerable。许多内置集合实现IEnumerable,但不实现IList(例如,字典、哈希集、哈希表、队列、堆栈等)。@Luke:如果它是一个列表(这是问题所暗示的),它将实现IList。@erikkallen,是的,但这是OP应该注意的。在给出的示例中,避免该问题只需将“if(myObject是IEnumerable)”更改为“if(myObject是IList)”。或者更简洁地说(如果使用
IEnumerable
),
Items.As()?.Cast()??Enumerable.Empty()
,表示:如果列表实现了
IEnumerable
且结果不为空,则将此泛型对象列表作为对象列表获取;否则,只需获取对象的空枚举。