为什么可以使用对象初始化将地址添加到 MailMessage.To?

Why can an address be added to MailMessage.To using object initialisation?

以下代码为何或如何工作:

var mail = new MailMessage
{
    To = { "hello@abc.com" }
};

鉴于 MailMessage.To 既是只读的 属性,又是赋值运算符?

据我所知,此语法会触发 MailAddressCollection 上的 Add 方法,但我找不到解释 MailAddressCollection 的这种魔法的文档,或者如果它与它派生的 Collection<T> 类型或它继承的接口有关。

为了表明上述语法被区别对待,以下方法给出了编译时错误,抱怨 To 属性 是只读的:

// Attempt 1

var mail = new MailMessage
{
    To = "hello@abc.com"
};

// Attempt 2

var mail = new MailMessage();
mail.To = { "hello@abc.com" }

// Attempt 3

var mail = new MailMessage
{
    To = new MailAddressCollection()
};

我敢肯定还有其他这种类型的初始化示例,但是 MailMessage 是我第一次遇到它。

让我们尝试一次一个地回答您的问题

Q1。为什么下面的代码有效?

var mail = new MailMessage
{
    To = { "hello@abc.com" }
};

A1。 To 属性 本质上是一个只读的 属性 ,您只能在对象构造期间分配一个值。 "magic" 由 Collection Initializer 提供,它使用该语法对 IEnumerable 的类型调用 AddMailAddressCollection 是一个 Collection<MailAddress> 又实现了 IEnumerable.

正如您推断的那样,该代码实际上等同于

var mail = new MailMessage();
mail.To.Add("hello@abc.com");

文档位于 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers

Q2。为什么以下代码不起作用?

A2。

Attempt1 - you can't assign a string to a collection
Attempt2 - the property is read-only
Attempt3 - the property is read-only