0

Could someone please explain how string interpolation is possible with null literals, like in the following example.

var output = "Hello" + null + " World"' => "Hello World"

My suspicion would be Operate Lifting, which appears to take default(string) whilst interpolating. Or a potential implicit conversion from Nullable<string> to string that returns default(string) in the case the input string is null.

Any assistance in helping my understanding would be much appreciated.

  • 1
    ...there is no C# string interpolation in your post: you are confusing concatenation with interpolation, and concatenation is not interpolation, and C#'s `String`'s `+` operator allows concatenation with `null` because it results in better _programmer ergonomics_ – Dai Feb 20 '23 at 22:42
  • 2
    The "lifted operator" concept only applies to value-types in C#/.NET (i.e. `struct` types and primitive values) that are contained within a `System.Nullable`, this does not apply to reference-types, including `String`, and [the C# language has a special-case rule that explicitly says that during concatenation `null` will be treated the same as `String.Empty`](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/addition-operator#string-concatenation). – Dai Feb 20 '23 at 22:47

1 Answers1

0

Could someone please explain how string interpolation is possible with null literals, like in the following example.

var output = "Hello" + null + " World";
Console.WriteLine( output ); // "Hello World"
  • Your post contains an example of string concatenation using the + operator.
  • Your post does not demonstrate string interpolation, which is a separate language feature that requires the use of $-prefixed string literals and {} placeholders, which can be compiled with very different semantics depending on the use-case (including trivial concatenation, or a FormattableString instance, and other weird things too, especially since C# 10 in 2022).
  • However, in both cases (string concatenation, and string interpolation), if any of the operands or arguments (respectively) are null then they are treated the same as a zero-length (empty) String (i.e. String.Empty).
    • This behaviour is specifically documented in the C# language guide's page on the + operator (emphasis mine):

      String concatenation

      When one or both operands are of type string, the + operator concatenates the string representations of its operands (the string representation of null is an empty string):

    • The behaviour is the same for other features of .NET and the BCL that involve concatenating, and interpolating, null references into, or with, String values, such as the static method String.Concat:

      An Empty string is used in place of any null element in values.


My suspicion would be Operate Lifting, which appears to take default(string) whilst interpolating. Or a potential implicit conversion from Nullable to string that returns default(string) in the case the input string is null.

  • Your thoughts are incorrect, sorry: C# 8.0's nullable-reference-types feature is unrelated to the C# 2.0 nullable-types feature, despite sharing the same shorthand syntax: so a String? declaration does not mean Nullable<String>.
    • Nullable<T> is used to represent nullable-value-types, and it cannot be used with reference-types like String. If you ever try to use Nullable<String> then you will get a compile-time error because T in Nullable<T> is constrained to value-types only.
    • Similarly, the operator lifting concept only applies to cases involving Nullable<T>. When reference-types (and so, null) is involved then the behaviour is entirely defined by the operator's implementation...
      • ...in most case this is a public static TResult operator+( TOperand1 left, TOperand2 right ) method.
      • However, String is an exception to this rule: there is no operator+ method defined on the String type and instead the compiler handles it itself, this is necessary because string literals can be concatenated at compile-time by the compiler itself.
      • Another exception is if the operator+( T left, String right ) on a different type is invoked, and in that case the String right operand might very-well be null, and dealing with that correctly is another problem and I don't want to get too sidetracked here.
Dai
  • 141,631
  • 28
  • 261
  • 374