将对象转换为通用列表

时间:2010-05-14 19:38:23

标签: c# generics list

我有3个generict类型列表。

List<Contact> = new List<Contact>();
List<Address> = new List<Address>();
List<Document> = new List<Document>();

并将其保存在类型为object的变量上。现在我已经做了Cast back to List来制作一个foreach,有些像这样:

List<Contact> = (List<Contact>)obj;

但是obj内容每次都在变化,我有一些这样的:

List<???> = (List<???>)obj;

我有另一个变量保持当前obj类型:

Type t = typeof(obj);

我可以这样做吗?:

List<t> = (List<t>)obj;

Obs:我没有列表中的当前类型,但我需要强制转换,而现在我不再使用另一种形式:

List<Contact> = new List<Contact>();

8 个答案:

答案 0 :(得分:29)

多么棘手的问题。试试这个:

List<Contact> c = null;
List<Address> a = null;
List<Document> d = null;

object o = GetObject();

c = o as List<Contact>;
a = o as List<Address>;
d = o as List<Document>;

在c,a和d之间,有2个空值和1个非空值,或3个空值。


拿2:

object o = GetObject();
IEnumerable e = o as IEnumerable;
IEnumerable<Contact> c = e.OfType<Contact>();
IEnumerable<Address> a = e.OfType<Address>();
IEnumerable<Document> d = e.OfType<Document>();

答案 1 :(得分:24)

大量的试验和错误在SL 5上给了我这个,但它也适用于普通的C#。您还需要将LINQ添加到您的使用列表中,以便后半部分正常工作。

    List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList()

享受!

答案 2 :(得分:2)

我遇到了同样的问题,并通过查看已铸造对象的目的解决了这个问题。你真的需要把它投射到特定的(封闭的)泛型类型吗?在我的情况下,(开放)泛型类型有一个我用来投射它的接口。

var list = obj as IUsefulInterface;

list.MethodThatIAmInterestedIn();

答案 3 :(得分:1)

这样的通用解决方案(使用基于System.Type对象的泛型参数实例化类型)是不可能的。如果你真的只是处理这三种类型,那么你很幸运,因为它很容易:

Type t = typeof(obj);

if (t == typeof(List<Contact>)) {
    var contactList = (List<Contact>)obj;
    // do stuff with contactList

} else if (t == typeof(List<Address>)) {
    var addressList = (List<Address>)obj;
    // do stuff with addressList

} else if (t == typeof(List<Document>)) {
    var documentList = (List<Document>)obj;
    // do stuff with documentList
}

答案 4 :(得分:1)

我在编写验证属性时遇到此问题,我从ValidationContext收到了一个对象并且知道它需要是一个列表,但不是它的列表。当我尝试将其转换为IEnumerable<object>时,它会抛出异常,但可以将其转换为IEnumerable,然后通过linq允许.Cast<object>()

最终有效的是:

var enumerable = listObject as IEnumerable;
var list = enumerable.Cast<object>().ToList();

答案 5 :(得分:0)

不,你不能在不转弯的情况下进行投射(这是:反射),必须在编译时知道泛型类型参数。你当然可以做这样的事情:

content.Where(o => o is type).ToList().Foreach(stuff);

答案 6 :(得分:0)

我遇到了同样的问题 - 我有一个集合,其数据类型仅在运行时已知,我无法将其转换为任何内容。以上解决方案均无效。最后,我通过序列化为JSON并反序列化来解决它。当然,这不是理想的,但可以帮助别人。

string jsonString = JsonConvert.SerializeObject(myObject);
jsonString = "{ values:" + jsonString + "}";

JObject j = JObject.Parse(jsonString);

//now we can iterate over the list
foreach (var x in j["values"])
{
    string name = x.ToString();
    ...
}

答案 7 :(得分:-1)

您可能需要这样做:

if(object is List)
{
    list = (List)object
}