C#6中的字符串插值和重写的ToString()

Dar*_*bio 12 c# string c#-6.0

鉴于以下课程:

public abstract class ValueBase
{
    public new abstract string ToString();
}

public class EmailAddress : ValueBase
{
    public MailAddress MailAddress { get; }

    public EmailAddress([NotNull] string address)
    {
        MailAddress = new MailAddress(address);
    }

    public override string ToString()
    {
        return MailAddress.Address;
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么:

var email = new EmailAddress("joe@bloggs.com");

string emailString1 = $"{email}";
string emailString2 = email.ToString();
Run Code Online (Sandbox Code Playgroud)

返回name(Namespace.EmailAddress)类型的字符串,而不是重写的ToString方法(joe@bloggs.com)?

Pan*_*vos 18

插值按预期工作,因为您的类不会覆盖Object.ToString().ValueBase定义一个隐藏而不是覆盖它的方法. Object.ToString

只需删除ToStringValueBase.在这种情况下,Email.AddressObject.ToString正确覆盖,插值将返回所需的结果.

具体来说,将ValueBase更改为:

public abstract class ValueBase
{
}
Run Code Online (Sandbox Code Playgroud)

制作测试代码

var email = new EmailAddress("joe@bloggs.com");
string emailString1 = $"{email}";
Run Code Online (Sandbox Code Playgroud)

返回 joe@bloggs.com

UPDATE

正如人们所建议的那样,ToString()可以添加基本方法来强制实现者ToString在他们的类中实现自定义方法.这可以通过定义abstract override方法来实现.

public abstract class ValueBase
{
    public abstract override string ToString();
}
Run Code Online (Sandbox Code Playgroud)

  • OP似乎想要强制执行`ToString`方法的自定义实现.最简单的方法是覆盖`ToString`来调用一些*other*abstract方法. (5认同)
  • @Luaan nope,最简单的方法是`public abstract override string ToString();` (4认同)

Fab*_*jan 6

好吧,$"{email}"字符串会自动转换string.Format("{0}", email)为此方法的第二个参数是类型params object[].所以它object在调用ToString()方法之前将所有值向上转换.在您的代码中,您只需将此方法替换为内部的新方法ValueBase,并且类中的override关键字EmailAddress实现此抽象方法而不是原始对象的方法.

如果将第二个值明确地转换为object,则可以轻松测试它:

var email = new EmailAddress("joe@bloggs.com");

string emailString1 = $"{email}";
string emailString2 = ((object)email).ToString();
Run Code Online (Sandbox Code Playgroud)

如您所见,现在也emailString2返回typename.您可以ToString()从抽象类中删除方法,让EmailAdress类实现对象ToString()或在抽象类中实现它.例如 :

    public abstract class ValueBase
    {
        // overrides object's ToString()
        public override string ToString()
        {
            return base.ToString();
        }
    }

    public class EmailAddress : ValueBase
    {
       ...

       // overrides ValueBase's ToString()
       public override string ToString()
       {
           return MailAddress.Address;
       }
    }
Run Code Online (Sandbox Code Playgroud)

使用此新代码,输出符合预期:

joe@bloggs.com
joe@bloggs.com
Run Code Online (Sandbox Code Playgroud)