无法将 Arraylist 中的对象与实际对象进行比较

Cannot compare object from Arraylist to the actual object

我正在尝试 select 数组列表中的随机用户控件。我得到了数组的索引,但它告诉我它 cannot simply convert int to UserControl。有人知道我做错了什么吗?

    ArrayList notiList = new ArrayList();

    int count = 0;
    int i;
    public MainPage()
    {
        this.InitializeComponent();

        foreach (NotiObject noti in itemsPanel.Children.Where(c => c is NotiObject))
        {
            notiList.Add(noti);
            System.Diagnostics.Debug.WriteLine(noti);

        }
        i = new Random().Next(0, notiList.Count);

    }

   
    void sendNotification()
    {
        NotiObject randomNoti = notiList.IndexOf(i);



    }

正如 Dai 所暗示的那样,ArrayList 是一个特别古老的东西,在 .net 相对较新并且没有被称为泛型的非常有用的功能的时代。

ArrayList 的手册页是这样说的(我的重点):

Important We don't recommend that you use the ArrayList class for new development. Instead, we recommend that you use the generic List class.

连制造商都说“不要使用这个产品”

ArrayList 的最大问题是因为它希望能够存储任何内容,所以它会将其内容保存在一个 object 数组

这意味着您可以将两个完全不相关的东西放在一起,如果这样做,您必须检查它们的类型,并且您总是必须进行强制转换才能将对象变回您想要的样子

notiList.Add(123); //whoops, that's not a NotiObject

foreach(var o in notiList)
  var n = (NotiObject)notiList[0]; //whoops, that's a crash
}

因此,使用它非常令人厌烦,尤其是您必须一直投射的部分。这很快就会变得无聊:

object o = "hello";
object p = "world";
object q = (string)o + (string)p;
object r = ((string)q).Substring(3).IndexOf((stribg)p);
r = (int)r + ((int)r)/2;

把所有的东西都存储在一个对象中是可以做到的,但是看看那是多么的乱七八糟。您必须开始将类型名称放入变量名称中,以帮助记住 r 是一个 int,而 q 是一个字符串 - 匈牙利表示法是过去的另一个遗迹。

当您将内容放入 ArrayList 时,这就是您所做的;将它们存储在 object


于是发明了泛型,发明了List。可以自定义的列表,用于存储单一类型的对象,如字符串、整数或 NotiObject

var nums = new List<int>();
nums.Add(123); //works

var notiList = new List<NotiObject>();
notiList.Add(123); //compiler refuses this one

说了这么多,可以回答你的问题了。此代码没有意义:

NotiObject randomNoti = notiList.IndexOf(i);

i 是一个整数。 IndexOf 是一种查找列表中项目的数字索引的方法。如果列表是 "a","b","c" 而你要求 IndexOf("b") 结果是 1 因为 b 在第二个索引处,索引从 0 开始。

IndexOf 不是“给我索引blahblah处的对象”,它是“告诉我这个对象blahblah的索引”

该代码没有意义,因为您传递了一个整数并且列表存储了 NotiObject。 IndexOf 永远不会在 NotiObject 列表中找到整数。这是第一个错误。您被允许这样做是因为 ArrayList 将所有内容都存储为对象,因此即使列表中没有整数,您也可以将整数传递给 IndexOf

IndexOf returns 一个整数。您不能将整数分配给 NotiObject 类型的变量。这是编译器抱怨的事情

即使你正确地形成了代码,你仍然必须投射:

NotiObject randomNoti = (NotiObject)notiList[i];

这一切都非常令人厌烦,如果您坚持使用 ArrayList 可能不会是您最后犯的错误


如果您使用 List<NotiObject>,则不允许将整数传递给 IndexOf;编译器会阻止你,这可能会让你在文档中评估 IndexOf,并看到它是为了从对象中找到 int 索引,而不是 int index

处的对象

你会写这样的代码:

List<NotiObject> notiList = new List<NotiList>();
...
NotiObject randomNoti = notiList[i];

没有演员表。如果您想详细了解为什么没有转换,请查看一些泛型的介绍性文章。简而言之,泛型(任何时候你看到 <T><TBlahBlah> 之类的东西)允许你指定类似于模板代码框架的东西,编译器使用它来为你创建代码;替换您要使用的对象类型的代码。不再有任何转换,因为编译器将编写一个完整的列表 class,它只适用于 NotiObjects