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.List1[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
且结果不为空,则将此泛型对象列表作为对象列表获取;否则,只需获取对象的空枚举。