Skip to content

Interpolated String Handlers: Implicit conversions to strings #5077

@333fred

Description

@333fred

In a previous LDM, we rejected defining a conversion from string to a custom handler type, saying that API authors should define one themselves if they so choose. However, this can cause some interesting issues with best common type that can require a language designer to explain why things work the way they do:

// No implicit conversion defined
using System;
var x = ((bool)(object)false) switch { true => default(CustomHandler), false => $"{1,2:f}Literal" }; // Error: no best common type
Console.WriteLine(x);
// Implicit conversion from CustomHandler to string
using System;
var x = ((bool)(object)false) switch { true => default(CustomHandler), false => $"{1,2:f}Literal" }; // x is string
Console.WriteLine(x);

public partial struct CustomHandler
{
    public static implicit operator string(CustomHandler c) => c.ToString();
}
// Implicit conversion from string to CustomHandler
using System;
var x = ((bool)(object)false) switch { true => default(CustomHandler), false => $"{1,2:f}Literal" }; // x is CustomHandler
Console.WriteLine(x);

public partial struct CustomHandler
{
    public static implicit operator CustomHandler(string c) => ...;
}

This type of friction can arise in a number of places, such as lambda type inference, ternary best type inference, or null-coalescing best type inference.

While I don't think we should define a language-level conversion here, I think we should make a recommendation (as a language) that interpolated string handler types define a conversion from string to themselves in order to help users with these scenarios.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions