[英]Why doesn't strings.Cast<object> cast List<string> to List<object>?
在这个问题中 ,有人建议我可以使用.Cast<object>
将一个泛型集合向上转换为一个对象集合。 在读了一下.Cast<>
,我仍然无法将它变成一个通用集合来转换成另一个泛型集合。 以下为什么不工作?
using System.Collections.Generic;
using System.Linq;
using System;
namespace TestCast2343
{
class Program
{
static void Main(string[] args)
{
List<string> strings = new List<string> { "one", "two", "three" };
//gives error: cannot convert from 'System.Collections.Generic.List<string>'
//to 'System.Collections.Generic.List<object>'
//IEnumerable<string> items = strings.Cast<object>();
//this works
strings.Cast<object>();
//but they are still strings:
foreach (var item in strings)
{
System.Console.WriteLine(item.GetType().Name);
}
//gives error: cannot convert from 'System.Collections.Generic.List<string>'
//to 'System.Collections.Generic.List<object>'
ProcessCollectionDynamicallyWithReflection(strings);
Console.ReadLine();
}
static void ProcessCollectionDynamicallyWithReflection(List<object> items)
{
//...
}
}
}
谢谢里德,这是我开始工作的代码:
using System.Collections.Generic;
using System.Linq;
using System;
namespace TestCast2343
{
class Program
{
static void Main(string[] args)
{
List<string> strings = new List<string> { "one", "two", "three" };
List<int> ints = new List<int> { 34, 35, 36 };
List<Customer> customers = Customer.GetCustomers();
ProcessCollectionDynamicallyWithReflection(strings.Cast<object>().ToList());
ProcessCollectionDynamicallyWithReflection(ints.Cast<object>().ToList());
ProcessCollectionDynamicallyWithReflection(customers.Cast<object>().ToList());
Console.ReadLine();
}
static void ProcessCollectionDynamicallyWithReflection(List<object> items)
{
foreach (var item in items)
{
Console.WriteLine(item.GetType().Name);
}
}
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string Location { get; set; }
public string ZipCode { get; set; }
public static List<Customer> GetCustomers()
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer { FirstName = "Jim", LastName = "Jones", ZipCode = "23434" });
customers.Add(new Customer { FirstName = "Joe", LastName = "Adams", ZipCode = "12312" });
customers.Add(new Customer { FirstName = "Jake", LastName = "Johnson", ZipCode = "23111" });
customers.Add(new Customer { FirstName = "Angie", LastName = "Reckar", ZipCode = "54343" });
customers.Add(new Customer { FirstName = "Jean", LastName = "Anderson", ZipCode = "16623" });
return customers;
}
}
}
你在滥用Cast<T>
。
首先,这里:
IEnumerable<string> items = strings.Cast<object>();
当你调用strings.Cast<object>()
,这将返回IEnumerable<object>
,而不是IEnumerable<string>
。 但是,集合中的项仍然是字符串,但保留在对象的引用中。
稍后,当您想将此传递给一个采用List<object>
,您需要将IEnumerable<T>
转换为IList<T>
。 这很容易就像这样:
// Cast to IEnumerabe<object> then convert to List<object>
ProcessCollectionDynamicallyWithReflection(strings.Cast<object>().ToList());
这是因为Cast<>
方法不返回List<T>
类型,而是返回IEnumerable<T>
。 将.ToList调用添加到结尾,它将解决问题。
strings.Cast<object>().ToList();
您还可以从另一个角度解决转换问题:修复ProcessCollectionDynamicallyWithReflection
因为它具有不必要的限制:
private static void ShowItemTypes(IEnumerable items)
{
foreach (object item in items)
{
string itemTypeName = (item != null) ? item.GetType().Name : "null";
Console.WriteLine(itemTypeName);
}
}
这应该工作:
IEnumerable<object> items = strings.Cast<object>();
此外,如果没有强制转换,则无法将IEnumerable作为List传递到ProcessCollectionDynamicallyWithReflection中。 所以,这甚至更好:
List<object> items = strings.Cast<object>().ToList();
在这个问题中,有人建议我可以使用
.Cast<object>
将一个泛型集合向上转换为一个对象集合
不,这不正确。 Cast
方法不会转换集合,它会转换集合中的每个项目,返回包含转换值的新集合。
您正在创建对象集合,但是您只需将其丢弃,因为您没有将其分配给变量。 (好吧,你实际上丢弃了一个能够创建集合的表达式,但这并不是那么相关。)
您需要将集合分配给变量以保留它,并且因为您需要List<object>
您需要将演员项放在列表中:
List<object> objects = strings.Cast<object>.ToList();
也许您应该考虑使用泛型而不是转换为对象:
static void ProcessCollectionDynamicallyWithReflection<T>(List<T> items)
这样,您可以在方法中编写强类型代码,并且您不必创建新集合只是为了能够将其发送到方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.