簡體   English   中英

無法將 object 從 Arraylist 與實際的 object 進行比較

[英]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);



    }

正如戴所暗示的那樣,ArrayList 是一個特別古老的東西,在 .net 相對較新並且沒有被稱為 generics 的非常有用的功能的時代。

ArrayList 的手冊頁這樣說(我強調):

重要我們不建議您使用 ArrayList class 進行新開發 相反,我們建議您使用通用列表 class。

甚至制造商都說“不要使用此產品”

ArrayList 的一個大問題是,因為它希望能夠存儲任何東西,所以它將其內容保存在一個object數組中

這意味着你可以把兩個完全不相關的東西放在一起,如果你這樣做,你必須檢查它們的類型,而且你總是必須轉換 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;

把所有東西都存到一個object里是可以的,但是看看這多亂啊。 您必須開始將類型名稱放入變量名稱中,以幫助記住 r 是一個 int,而 q 是一個字符串——匈牙利表示法是過去的另一個遺跡。

當你把東西放在 ArrayList 中時,這就是你在做的事情; 將它們存儲在object


於是發明了generics,發明了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是一個 integer。IndexOf 是一種查找列表中項目的數字索引的方法。 如果列表是"a","b","c"並且你要求IndexOf("b")結果是 1 因為 b 在第二個索引處,索引從 0 開始。

IndexOf不是“給我 object at index blahblah”,而是“告訴我這個 object blahblah 的索引”

該代碼沒有意義,因為您已經傳遞了一個 integer 並且列表存儲了 NotiObject。 IndexOf 永遠不會在 NotiObject 列表中找到 integer。 這是第一個錯誤。 您被允許這樣做是因為 ArrayList 將所有內容都存儲為對象,因此即使列表中沒有整數,您也可以將 integer 傳遞給 IndexOf

IndexOf 返回 integer。您不能將 integer 分配給 NotiObject 類型的變量。 這是編譯器抱怨的事情

即使你正確地形成了代碼,你仍然需要轉換:

NotiObject randomNoti = (NotiObject)notiList[i];

這一切都非常令人厭煩,如果你堅持使用 ArrayList 可能不是你最后犯的錯誤


如果您使用List<NotiObject> ,則不允許將 integer 傳遞給 IndexOf; 編譯器會阻止你,這可能會讓你在文檔中評估 IndexOf,並看到它是為了從 object 中找到 int 索引,而不是 object at int index

你會寫這樣的代碼:

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

沒有演員。 如果您想詳細了解為什么沒有轉換,請查看 generics 的一些介紹性文章。簡而言之,generics(任何時候您看到類似<T><TBlahBlah>的內容)允許您指定類似模板代碼框架的內容編譯器用來為你創建代碼; 將 替換為您要使用的 object 的代碼。 不再有任何轉換,因為編譯器將編寫一個完整的列表 class,它專門只適用於 NotiObjects

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM