135 votes

Existe-t-il un "String.Format" capable d'accepter des paramètres d'entrée nommés au lieu de placeholders d'index ?

Voilà ce que je sais

str = String.Format("Her name is {0} and she's {1} years old", "Lisa", "10");

Mais je veux quelque chose comme

str = String("Her name is @name and she's @age years old");
str.addParameter(@name, "Lisa");
str.addParameter(@age, 10);

179voto

Fabien PERRONNET Points 2943

En C# 6, vous pouvez utiliser interpolation de chaînes de caractères :

string name = "Lisa";
int age = 20;
string str = $"Her name is {name} and she's {age} years old";

Comme Doug Clutter mentionné dans son commentaire L'interpolation de chaînes de caractères prend également en charge chaîne de format . Il est possible de changer le format en le spécifiant après un deux-points. L'exemple suivant produira un nombre avec une virgule et deux décimales :

var str = $"Your account balance is {balance:N2}"

Comme Bas mentionné dans sa réponse L'interpolation de chaînes de caractères ne prend pas en charge les chaînes de caractères modèles. En fait, elle n'a pas de support intégré pour cela. Heureusement, il existe des bibliothèques de qualité.


SmartFormat.NET par exemple, prend en charge les caractères de remplacement nommés :

Smart.Format("{Name} from {Address.City}, {Address.State}", user)

// The user object should at least be like that 

public class User
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string State { get; set; }
}

Il est disponible sur NuGet .


Moustache est également une excellente solution. Bas a bien décrit ses avantages dans sa réponse .

60voto

Chakrava Points 393

Si vous ne disposez pas de C#6 dans votre projet, vous pouvez utiliser la fonction .Aggregate() de Linq :

    var str = "Her name is @name and she's @age years old";

    var parameters = new Dictionary<string, object>();
    parameters.Add("@name", "Lisa");
    parameters.Add("@age", 10);

    str = parameters.Aggregate(str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));

Si vous voulez quelque chose correspondant à la syntaxe spécifique de la question, vous pouvez créer une classe assez simple basée sur Aggregate :

public class StringFormatter{

    public string Str {get;set;}

    public Dictionary<string, object> Parameters {get;set;}

    public StringFormatter(string p_str){
        Str = p_str;
        Parameters = new Dictionary<string, object>();
    }

    public void Add(string key, object val){
        Parameters.Add(key, val);
    }

    public override string ToString(){
        return Parameters.Aggregate(Str, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
    }

}

Utilisable comme :

var str = new StringFormatter("Her name is @name and she's @age years old");
str.Add("@name", "Lisa");
str.Add("@age", 10);

Console.WriteLine(str);

Notez qu'il s'agit d'un code propre, conçu pour être facile à comprendre et performant.

35voto

Bas Brekelmans Points 13799

Si vous êtes d'accord pour attribuer une variable locale qui contient les données que vous utilisez pour remplacer les paramètres du modèle, vous pouvez utiliser la fonction C# 6.0 fonction d'interpolation des chaînes de caractères .

Le principe de base est que vous pouvez effectuer une logique de remplacement de chaîne assez avancée sur la base des données d'entrée.

Un exemple simple :

string name = "John";
string message = $"Hello, my name is {name}."

Exemple complexe :

List<string> strings = ...
string summary = $"There are {strings.Count} strings. " 
  + $"The average length is {strings.Select(s => s.Length).Average()}"

Inconvénients :

  • Pas de prise en charge des modèles dynamiques (par exemple, à partir d'un fichier de ressources)

Avantages (majeurs) :

  • Elle applique contrôles au moment de la compilation sur le remplacement de votre modèle.

Une solution open source agréable qui a presque la même syntaxe, est Moustache . D'après ce que j'ai pu trouver, deux implémentations C# sont disponibles. moustache pointue et Nustache .

J'ai travaillé avec mustache-sharp et j'ai constaté qu'elle n'a pas la même puissance que l'interpolation des chaînes, mais qu'elle s'en rapproche. Par exemple, vous pouvez faire ce qui suit (volé de sa page github).

Hello, {{Customer.Name}}
{{#newline}}
{{#newline}}
{{#with Order}}
{{#if LineItems}}
Here is a summary of your previous order:
{{#newline}}
{{#newline}}
{{#each LineItems}}
    {{ProductName}}: {{UnitPrice:C}} x {{Quantity}}
    {{#newline}}
{{/each}}
{{#newline}}
Your total was {{Total:C}}.
{{#else}}
You do not have any recent purchases.
{{/if}}
{{/with}}

19voto

Steve Points 3757

Avec C# 6, vous pouvez utiliser Interpolation des chaînes de caractères pour ajouter directement des variables dans une chaîne de caractères.

Par exemple :

string name = "List";
int age = 10;

var str = $"Her name is {name} and she's {age} years old";

Notez que l'utilisation du signe dollar ( $ ) avant le format de la chaîne.

18voto

Artem Points 1013

Alors pourquoi ne pas simplement remplacer ?

string str = "Her name is @name and she's @age years old";
str = str.Replace("@name", "Lisa");
str = str.Replace("@age", "10");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X