2009-02-18 3 views
4

Есть ли способ связи с String.Format без каких-либо определений {1}, {2}, и т. Д.? Возможно ли иметь какую-то форму автоинкремента? (Подобно обычным старым printf)Могу ли я передавать параметры в String.Format без указания номеров?

+0

Что цель не используя цифры? Возможно, если мы сможем следить за тем, почему вы хотите избежать их использования, мы помогаем с более полезным решением ... – BenAlabaster

+3

У меня есть около 20 параметров, и писать число для каждого из них громоздко. Я также боюсь, что могу пропустить номер или использовать номер дважды. И я чувствую, что удобство обслуживания без номеров может быть проще. –

+0

Понятное, я полагаю ... Я всегда считаю это трудоемким, если я хочу встраивать еще не форматированные строки в другие, но не форматированные строки ... а затем добавить параметры в конце процесса, который также имеет те же недостатки. – BenAlabaster

ответ

2

Не бойтесь - где бы он помещал объекты в строку? Используя printf, вам все равно нужно указывать спецификаторы.

+1

Да, я не против использования спецификаторов, но я не хочу жестко кодировать индексы. –

+0

@Hosam - это с целью встраивания других форматируемых строк в составные строки, а затем добавления всех параметров на более позднем этапе? – BenAlabaster

+0

@balabaster: нет, это один вызов 'String.Format' для вставки нескольких переменных. –

5

Вы можете использовать решение named string formatting, которое может решить ваши проблемы.

+0

Спасибо. Приятно знать об этом. –

0

Можно всегда использовать это (непроверенные) метод, но я чувствую, что над комплексом:

public static string Format(char splitChar, string format, 
          params object[] args) 
{ 
    string splitStr = splitChar.ToString(); 
    StringBuilder str = new StringBuilder(format + args.Length * 2); 
    for (int i = 0; i < str.Length; ++i) 
    { 
     if (str[i] == splitChar) 
     { 
      string index = "{" + i + "}"; 
      str.Replace(splitStr, index, i, 1); 
      i += index.Length - 1; 
     } 
    } 

    return String.Format(str.ToString(), args); 
} 
0

Я придумал это, опять-таки это немного но он отлично работает для того, что мне нужно было сделать, чтобы передать переменное число или аргументы моей собственной функции так же, как я использовал WriteLine. Я надеюсь, что это помогает кому-то

protected void execute(String sql, params object[] args) 
{ 
    for (int i = 0; i < args.Count(); i++) 
    { 
     sql = sql.Replace(String.Format("{{{0}}}", i), args[i].ToString()); 
    } 
    //... 
} 
+0

Не могли бы вы рассказать мне, в какой программе вы это реализовали? Я бы хотел сделать SQL-инъекцию. Поэтому, если честно, вам стоит подумать о замене этого с помощью ['SqlParameter'] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.aspx) в [' SqlCommand'] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx) – Oliver

1

Я думаю, что лучший способ - передать имена свойств вместо Numbers. использовать этот метод:

using System.Text.RegularExpressions; 
using System.ComponentModel; 

public static string StringWithParameter(string format, object args) 
    { 
     Regex r = new Regex(@"\{([A-Za-z0-9_]+)\}"); 

     MatchCollection m = r.Matches(format); 

     var properties = TypeDescriptor.GetProperties(args); 

     foreach (Match item in m) 
     { 
      try 
      { 
       string propertyName = item.Groups[1].Value; 
       format = format.Replace(item.Value, properties[propertyName].GetValue(args).ToString()); 
      } 
      catch 
      { 
       throw new FormatException("The string format is not valid"); 
      } 
     } 

     return format; 
    } 

Представьте у вас есть студенческий класс со свойствами, как: Имя, LastName, BirthDateYear и использовать его как:

Student S = new Student("Peter", "Griffin", 1960); 
string str = StringWithParameter("{Name} {LastName} Born in {BithDate} Passed 4th grade", S); 

и вы получите: Питер Гриффин родился в 1960 год прошел 4-й класс.

0

Если кто-то заинтересован, я изменил решение ашкан, чтобы иметь возможность запускать его под WinRT:

/// <summary> 
/// Formats the log entry. 
/// /// Taken from: 
/// http://stackoverflow.com/questions/561125/can-i-pass-parameters-to-string-format-without-specifying-numbers 
/// and adapted to WINRT 
/// </summary> 
/// <param name="format">The format.</param> 
/// <param name="args">The arguments.</param> 
/// <returns></returns> 
/// <exception cref="System.FormatException">The string format is not valid</exception> 
public static string FormatLogEntry(string format, object args) 
{ 
    Regex r = new Regex(@"\{([A-Za-z0-9_]+)\}"); 

    MatchCollection m = r.Matches(format); 

    var properties = args.GetType().GetTypeInfo().DeclaredProperties; 

    foreach (Match item in m) 
    { 
     try 
     { 
      string propertyName = item.Groups[1].Value; 
      format = format.Replace(item.Value, properties.Where(p=>p.Name.Equals(propertyName)) 
       .FirstOrDefault().GetValue(args).ToString()); 
     } 
     catch 
     { 
      throw new FormatException("The string format is not valid"); 
     } 
    } 

    return format; 
} 
Смежные вопросы