Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# - dynamic string interpolation [duplicate]

I'm trying to format some string dynamically with available variables in a specific context/scope.

This strings would have parts with things like {{parameter1}}, {{parameter2}} and these variables would exist in the scope where I'll try to reformat the string. The variable names should match.

I looked for something like a dynamically string interpolation approach, or how to use FormattableStringFactory, but I found nothing that really gives me what I need.

var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{{parameter2}} Today we're {{parameter1}}";
var result = MagicMethod(retrievedString, parameter1, parameter2);
// or, var result = MagicMethod(retrievedString, new { parameter1, parameter2 });

Is there an existing solution or should I (in MagicMethod) replace these parts in the retrievedString with matching members of the anonymous object given as parameter (using reflection or something like that)?

EDIT:

Finally, I created an extension method to handle this:

internal static string SpecialFormat(this string input, object parameters) {
  var type = parameters.GetType();
  System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex( "\\{(.*?)\\}" );
  var sb = new System.Text.StringBuilder();
  var pos = 0;

  foreach (System.Text.RegularExpressions.Match toReplace in regex.Matches( input )) {
    var capture = toReplace.Groups[ 0 ];
    var paramName = toReplace.Groups[ toReplace.Groups.Count - 1 ].Value;
    var property = type.GetProperty( paramName );
    if (property == null) continue;
    sb.Append( input.Substring( pos, capture.Index - pos) );
    sb.Append( property.GetValue( parameters, null ) );
    pos = capture.Index + capture.Length;
  }

  if (input.Length > pos + 1) sb.Append( input.Substring( pos ) );

  return sb.ToString();
}

and I call it like this:

var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{parameter2} Today we're {parameter1}";
var result = retrievedString.SpecialFormat( new { parameter1, parameter2 } );

Now, I don't use double braces anymore.

like image 919
Jin-K Avatar asked Jul 09 '18 09:07

Jin-K


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

You can use reflection coupled with an anonymous type to do this:

public string StringFormat(string input, object parameters)
{
    var properties = parameters.GetType().GetProperties();
    var result = input;

    foreach (var property in properties)
    {
        result = result.Replace(
            $"{{{{{property.Name}}}}}", //This is assuming your param names are in format "{{abc}}"
            property.GetValue(parameters).ToString());
    }

    return result;
}

And call it like this:

var result = StringFormat(retrievedString, new { parameter1, parameter2 });
like image 101
DavidG Avatar answered Sep 29 '22 23:09

DavidG


While not understanding what is the dificulty you're having, I'm placing my bet on

Replace( string oldValue, string newValue )

You can replace your "tags" with data you want.

var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{{parameter2}} Today we're {{parameter1}}";
var result = retrievedString.Replace("{{parameter2}}", parameter2).Replace({{parameter1}}, parameter1);

EDIT

Author mentioned that he's looking at something that will take parameters and iterate the list. It can be done by something like

public static void Main(string[] args)
    {
        //your "unmodified" srting
        string text = "{{parameter2}} Today we're {{parameter1}}";

        //key = tag(explicitly) value = new string
        Dictionary<string, string> tagToStringDict = new Dictionary<string,string>();

        //add tags and it's respective replacement
        tagToStringDict.Add("{{parameter1}}", "Foo");
        tagToStringDict.Add("{{parameter2}}", "Bar");

        //this returns your "modified string"
        changeTagWithText(text, tagToStringDict);
    }

    public static string changeTagWithText(string text, Dictionary<string, string> dict)
    {
        foreach (KeyValuePair<string, string> entry in dict)
        {
            //key is the tag ; value is the replacement
            text = text.Replace(entry.Key, entry.Value);
        }
        return text;
    }

The function changeTagWithText will return:

"Bar Today we're Foo"

Using this method you can add all the tags to the Dictionary and it'll replace all automatically.

like image 29
zakharuk_pasha Avatar answered Sep 30 '22 01:09

zakharuk_pasha