【问题标题】:Why can an address be added to MailMessage.To using object initialisation?为什么可以将地址添加到 MailMessage.To 使用对象初始化?
【发布时间】:2018-09-28 01:13:55
【问题描述】:

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

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 是我第一次遇到它。

【问题讨论】:

    标签: c# properties initialization c#-7.0


    【解决方案1】:

    让我们一次一个地回答你的问题

    第一季度。为什么下面的代码有效?

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

    A1。 To 属性本质上是一个只读属性,您只能在对象构造期间为其赋值。 “魔法”由 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的文档

    第二季度。为什么以下代码不起作用?

    A2。

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

    【讨论】:

    • 好的,所以它使用集合初始化器语法,我不关注的是它如何绕过Toreadonly 方面。我认为只读属性只能从构造函数中设置,并且对象初始化器语法发生在构造函数调用之后。有没有关于步骤初始化顺序的文档?
    • To 在构造函数内部赋值。请注意,您没有执行“To = new MailAddressCollection {“me@email.com”}”,因此您没有违反 readonly 修饰符
    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2014-08-30
    • 2013-06-27
    相关资源
    最近更新 更多