dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.02k stars 4.03k forks source link

String Interpolation Question #3916

Closed VaclavElias closed 9 years ago

VaclavElias commented 9 years ago

Hi,

How can I do such a simple thing like this, is it meant to work, is it working, can it work?

..
string welcome = "";
if (lang=="en") { welcome = "Hello, {name}. How are you?"; }
else if (lang=="es") { welcome = "Hola {name}. Como estas?"; } 
..
return welcome;

And somewhere else in the code I would simple request the string which could come from anywhere, e.g. database, ..

public void Main()
{
  string intro = GiveMeIntro("en");
  string name = "Vaclav";
  Console.WriteLine($intro);
}

Let's do not assume that I can send the name here

string intro = GiveMeIntro("en", "Vaclav");

Let's assume that these are coming from database

01 intro en "Hello, {name}. How are you?"
02 intro es "Hola {name}. Como estas?"

If I am right, the old school way it would be working?

..
string welcome = "";
if (lang=="en") { welcome = "Hello, {0}. How are you?"; }
else if (lang=="es") { welcome = "Hola {0}. Como estas?"; } 
..
return welcome;
public void Main()
{
  string intro = GiveMeIntroOldWay("en");
  string name = "Vaclav";
  Console.WriteLine(intro, name);
}

Is there any way to make c# 6.0 to work that $ followed by string would interpolate that string? Any work around I am not aware of?

If that is not possible, don't you think that the new functionality lost a certain feature it could have?

Hope that all I wrote makes sense?

Update: Just realized, that maybe it is for security reason as I could inject e.g this {DateTime.Now} or anything to such a string if it worked as I would like.

01 intro en "Hello, {name}. How are you?"
02 intro es "Hola {name}. Como estas?"
03 intro fr "Hola {DateTime.Now}. Got ya?"

Thanks :)

AdamSpeight2008 commented 9 years ago

Have you considered multiple argument in the format string?

VaclavElias commented 9 years ago

Sure, one argument or multiple I would have the same query about this for c# experts and creators. I just demonstrated one argument :)

Bill-McC commented 9 years ago

I doubt thus would be possible as such unless you are doing some on the fly lookup of local variables and parsing of resource strings for code expressions: such a thing would be relatively expensive. So instead of named placeholders you'd have to use {1} etc with string.format. I guess you could have the resource strings use named placeholders, and at runtime do a replace of {name} with {1} etc.

Joe4evr commented 9 years ago

You can't put a $ in front of a string reference and "magically" make it an interpolated string. This is better solved by rewriting it more like this:

public string Greet(string lang, string name)
{
    if(lang == "en") return $"Hello, {name}. How are you?";
    else if(lang == "es") return $"Hola {name}. Como estas?";
    //etc.
}
VaclavElias commented 9 years ago

Thank you Bill-McC and Joe4evr, both your suggestions would do it and I will stick with them. Thank you for your help. I agree, let's don't do magic :) and let's close this thread.

ufcpp commented 9 years ago
using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Greet("en")); // Hello, {0}. How are you?
        Console.WriteLine(Greet("es")); // Halo {0}. Como estas?
    }

    public static string Greet(string lang)
    {
        Func<string, FormattableString> f = name =>
        {
            if (lang == "en") return $"Hello, {name}. How are you?";
            else if (lang == "es") return $"Hola {name}. Como estas?";
            //etc.
            return $"{name}";
        };

        return f(null).Format;
    }
    }
}
VaclavElias commented 9 years ago

Thank you ufcpp :+1: I take this also as a very nice option! :)