C# 为什么';t弦。铸造<;对象>;演员名单<;字符串>;列出<;对象>;?

C# 为什么';t弦。铸造<;对象>;演员名单<;字符串>;列出<;对象>;?,c#,generics,C#,Generics,在中,有人建议我可以使用.cast将通用集合向上强制转换为对象集合。之后,我仍然无法将它转换为另一个通用集合为什么以下操作不起作用? using System.Collections.Generic; using System.Linq; using System; namespace TestCast2343 { class Program { static void Main(string[] args) { List

在中,有人建议我可以使用
.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)
        {
            //...
        }
    }

}
使用System.Collections.Generic;
使用System.Linq;
使用制度;
命名空间TestCast2343
{
班级计划
{
静态void Main(字符串[]参数)
{
列表字符串=新列表{“一”、“二”、“三”};
//给出错误:无法从“System.Collections.Generic.List”转换
//至“System.Collections.Generic.List”
//IEnumerable items=strings.Cast();
//这很有效
strings.Cast();
//但它们仍然是字符串:
foreach(字符串中的变量项)
{
System.Console.WriteLine(item.GetType().Name);
}
//给出错误:无法从“System.Collections.Generic.List”转换
//至“System.Collections.Generic.List”
ProcessCollectionDynamicallyWithReflection(字符串);
Console.ReadLine();
}
静态void ProcessCollectionDynamicallyWithReflection(列表项)
{
//...
}
}
}
答复: 谢谢你,里德,这是我的代码:

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;
        }
    }
}
使用System.Collections.Generic;
使用System.Linq;
使用制度;
命名空间TestCast2343
{
班级计划
{
静态void Main(字符串[]参数)
{
列表字符串=新列表{“一”、“二”、“三”};
List ints=新列表{34,35,36};
List customers=Customer.GetCustomers();
ProcessCollectionDynamicallyWithReflection(strings.Cast().ToList());
ProcessCollectionDynamicWithReflection(ints.Cast().ToList());
ProcessCollectionDynamicWithReflection(customers.Cast().ToList());
Console.ReadLine();
}
静态void ProcessCollectionDynamicallyWithReflection(列表项)
{
foreach(项目中的var项目)
{
Console.WriteLine(item.GetType().Name);
}
}
}
公共类客户
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串Street{get;set;}
公共字符串位置{get;set;}
公共字符串ZipCode{get;set;}
公共静态列表GetCustomers()
{
列出客户=新列表();
添加(新客户{FirstName=“Jim”,LastName=“Jones”,ZipCode=“23434”});
添加(新客户{FirstName=“Joe”,LastName=“Adams”,ZipCode=“12312”});
添加(新客户{FirstName=“Jake”,LastName=“Johnson”,ZipCode=“23111”});
添加(新客户{FirstName=“Angie”,LastName=“Reckar”,ZipCode=“54343”});
添加(新客户{FirstName=“Jean”,LastName=“Anderson”,ZipCode=“16623”});
返回客户;
}
}
}

这是因为
Cast
方法不返回
列表
类型,而是返回
IEnumerable
。在末尾添加一个.ToList调用,它将修复该问题

strings.Cast<object>().ToList();
strings.Cast().ToList();
您使用不当

首先,这里:

IEnumerable<string> items = strings.Cast<object>();
IEnumerable items=strings.Cast();
调用
strings.Cast()
时,将返回
IEnumerable
,而不是
IEnumerable
。但是,集合中的项仍然是字符串,但保留在对对象的引用中

稍后,当您想将其传递到采用
列表的方法时,需要将
IEnumerable
转换为
IList
。这样做很容易:

// Cast to IEnumerabe<object> then convert to List<object>
ProcessCollectionDynamicallyWithReflection(strings.Cast<object>().ToList());
//转换为IEnumerabe,然后转换为List
ProcessCollectionDynamicallyWithReflection(strings.Cast().ToList());
这应该可以:

IEnumerable<object> items = strings.Cast<object>();
IEnumerable items=strings.Cast();
此外,在没有强制转换的情况下,不能将IEnumerable作为列表传递到ProcessCollectionDynamicWithReflection中。因此,这甚至更好:

List<object> items = strings.Cast<object>().ToList();
List items=strings.Cast().ToList();
有人在这个问题上提出, 我可以铸造一个通用的集合 向上移动到具有
.Cast

不,那是不对的。
Cast
方法不强制转换集合,它强制转换集合中的每个项,返回包含强制转换值的新集合

您正在创建对象的集合,但由于没有将其分配给变量,因此您将其丢弃。(实际上,您正在丢弃一个能够创建集合的表达式,但这并不重要。)

您需要将集合分配给一个变量以保留它,并且由于您需要一个
列表
,您需要将强制转换项放入一个列表中:

List<object> objects = strings.Cast<object>.ToList();
List objects=strings.Cast.ToList();

也许你应该考虑使用泛型而不是铸造为对象:

static void ProcessCollectionDynamicallyWithReflection<T>(List<T> items)
static void processCollectionDynamicWithReflection(列表项)

这样,您就可以在方法中编写强类型代码,而不必创建新的集合就可以将其发送到该方法。

您还可以从另一个角度解决强制转换问题:修复
ProcessCollectionDynamicallyWithReflection
,因为它具有不必要的限制:

private static void ShowItemTypes(IEnumerable items)
{
    foreach (object item in items)
    {
        string itemTypeName = (item != null) ? item.GetType().Name : "null";
        Console.WriteLine(itemTypeName);
    }
}

Mesleading:代码不会将
IEnumerable
转换为
列表
,而是使用
IEnumerable
中的项目创建一个新的
列表
。是。这不是演员阵容,而是完全的转变。Cast与之类似,但也不只是一个单一的强制转换操作,而是生成一个新的可枚举序列。