Output syntax different ways

Lets Create a Class of Product

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1.Models
{
    public class Product
    {
        public string Name { get; set; }
        public int Price { get; set; }
        public string Unit { get; set; }
        public string ProductType { get; set; }
        public Product RelatedProduct { get; set; }
    }
}

Write the following code to program.cs file

Product product = new Product()
{
    Name = "Laptop",
    Price = 100000,
    ProductType = "Electronics",
    Unit = "pcs"
};

List<Product> products = new List<Product>() {

    new Product()
    {
        Name = "Mouse",
        Price  = 200,
        ProductType = "Electronics",
        Unit = "pcs"
    },
    new Product()
    {
        Name = "Keyboard",
        Price  = 600,
        ProductType = "Computer",
        Unit = "pcs"
    },
    product
};

foreach (var item in products)
{
    // 1st way to output
    //Console.WriteLine("Name: " + item.Name + " Price: " + item.Price + " Related Product: "+(item?.RelatedProduct?.Name?? "N/A"));

    // 2nd way to output
    //Console.WriteLine(string.Format("Name: {0} Price: {1} Related Product: {2}", item.Name, item.Price, (item?.RelatedProduct?.Name ?? "N/A")));

    // 3rd way to output
    string message = $"Name: {item.Name} Price: {item.Price}, Related Product: {(item?.RelatedProduct?.Name ?? "N/A")}";
    Console.WriteLine(message);

    // 4th way to output
    string message2 = $"{nameof(item.Name)}: {item.Name} {nameof(item.Price)}: {item.Price}, {nameof(item.RelatedProduct)}: {(item?.RelatedProduct?.Name ?? "N/A")}";
    Console.WriteLine(message2);
}