需要澄清c#中的基本索引器和集合

本文关键字:索引 集合 | 更新日期: 2023-09-27 18:09:07

我正在浏览另一个开发人员的代码,如下所示:

[XmlElement("AdminRecipient")] public AdminRecipient[] AdminRecipientCollection = new AdminRecipient[0];
        public AdminRecipient this[ string type ]
        {
            get
            {
                AdminRecipient result = null;
                foreach( AdminRecipient emailRecipient in AdminRecipientCollection )
                {
                    if( emailRecipient.Type == type )
                    {
                        result = emailRecipient;
                        break;
                    }
                }
                return( result );
            }           

谁能解释一下这一行会发生什么?

public AdminRecipient[] AdminRecipientCollection = new AdminRecipient[0];

包含所有电子邮件收件人的XML文件大约有5个电子邮件地址。但是通过使用[0],foreach循环会返回每个电子邮件地址吗?

我对索引器有一个基本的了解,但我不知道这个。它是做什么的?:

public AdminRecipient this[ string type ]

最后,这里的问题是,当所有5个收件人都在xml文件中时,应用程序不发送电子邮件。如果我将5个地址替换为1个电子邮件地址,那么我就能够收到电子邮件(这让我相信这里有一个逻辑问题)。

需要澄清c#中的基本索引器和集合

索引器允许您使用与数组访问相同语法的类型。一个最简单的例子是List<T>:

List<string> x = new List<string>();
x.Add("Item 0");
x.Add("Item 1");
string y = x[0]; // "Item 0"

x[0]的使用是调用List<T>的索引器。现在对于List<T>,索引是一个整数,就像它是一个数组一样,但它不必是。例如,对于Dictionary<TKey, TValue>,它的键类型是:

Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("foo", "bar");
string fetched = dictionary["foo"]; // fetched = "bar"

你也可以在索引器上设置setter:

dictionary["a"] = "b";

您的索引器只是返回数组中具有匹配类型的第一个AdminRecipient -如果找不到匹配,则返回null。

(顺便说一下,很不幸,您所展示的代码也使用了公共字段。它作为一个属性会更好——可能也不是一个数组。但那是另一个单独的讨论)

编辑:关于你突出显示的第一行:

public AdminRecipient[] AdminRecipientCollection = new AdminRecipient[0];

这将创建一个没有元素的数组,并为AdminRecipientCollection字段分配一个引用。如果没有进一步的更改,foreach循环将没有任何可迭代的内容,并且索引器将始终返回null。

然而,可能是其他东西——比如XML序列化——给该字段赋了不同的值——用更有用的数据填充它。

您正在询问的行是将AdminRecipientCollection赋值给空数组。这个赋值将在实例化时发生。如果有的话,XML的反序列化将在类实例化之后进行。作者在这里的目的大概是确保AdminRecipientCollection永远不会为空,即使在XML反序列化到它之前使用该类。

通过确保AdminRecipientCollection永远不为空,作者可以忽略foreach循环抛出NullReferenceException的可能性。至少,这可能是希望。

不幸的是,由于AdminRecipientCollection是公共的,AdminRecipient属性仍然可能抛出,如下所示:

var demoClass = new DemoClass();
demoClass.AdminRecipientCollection = null;
var firstRecipient = demoClass[0];

要防止这种可能性,请在开始枚举之前删除初始赋值并检查AdminRecipient属性是否为null。