无法将 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
我正在尝试 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