当我只能访问其对象时,如何将项添加到列表中?

时间:2016-02-07 09:51:13

标签: c# generics generic-list

某处在我的应用程序中,我有一个通用列表,它是使用反射从另一个程序集创建的。我只能访问该列表的对象。我的意思是我有一个Object objectOfList我知道它是一个通用的值列表(例如int或float值)。我需要在此列表中添加项目。我怎么能这样做?

由于我不知道泛型列表的类型是什么,我试图将objectOfList强制转换为对象列表,但它会引发异常:

(objectOfList as List<object>).Add(value); // value is an integer here

抛出空引用异常。

更新

可以是int float或任何其他类型。我编写代码时不知道类型是什么。这是从UI中选择列表类型的用户,然后创建列表。

4 个答案:

答案 0 :(得分:1)

正如李指出的那样,你必须使用实际的类型,而不是object。请考虑以下事项:

object someList = new List<int>();
(someList as List<object>).Add(1);

这将抛出NullReferenceException

(someList as List<int>).Add(1);

没有。

有关as的更多信息:

  

as运算符就像一个强制转换操作。但是,如果转换不可能,则返回null而不是引发异常

as (C# reference)

还有一件事你可以尝试,那就是通过使用非通用接口List<T>而失去IList的通用类型安全支持。这将允许您执行您想要的操作,但如果类型不同,则会抛出System.ArgumentException

(someList as IList).Add(1); //ok
(someList as IList).Add("hello");  //throws exception

答案 1 :(得分:1)

列表是不变的,因此您只能将其强制转换回具有相同元素类型的列表,例如

int value = 4;
object source = new List<int>();
((List<int>)source).Add(value);

如果您知道元素类型将始终与value的类型匹配,并且您可以静态地知道value的类型,那么您可以进行投射。

如果您知道列表元素类型可能是value的超类型,那么您可以调用IList.Add而不是安全的,例如

object source = new List<Animal>();
var g = new Giraffe();
((IList)source).Add(g);

请注意,在这种情况下,您无法将source投射到List<Giraffe>

如果您不知道value的静态类型,那么您还必须转发IList并准备好在调用Add时处理异常。

答案 2 :(得分:0)

Object objectOfList无法转换为List<object>,因此as运算符返回null。

如果您将其初始化为List<Object> objectOfListObject objectOfList = new List<Object>();,则您无法获得空引用。 E.g。

    Object objectOfList = new List<object>();
    (objectOfList as List<object>).Add(5); 

Example fiddle

答案 3 :(得分:0)

尝试将对象列表转换回原来的状态。如果它是一个列表,那么:

  

List lo =((List)objectOfList)

这样您就可以使用列表了。 然后,您可以通过此方法找出它的列表类型:

  

objectOfList.ToString()   要么   objectOfList.GetType()。toString()方法