С именем String.Format, возможно ли это?
Вместо использования {0} {1}
и т.д. вместо этого я хочу использовать {title}
. Затем заполните эти данные каким-то образом (ниже я использовал Dictionary
). Этот код недействителен и выдает исключение. Я хотел знать, могу ли я сделать что-то похожее на то, что хочу. Использование {0 .. N}
не является проблемой. Мне было просто любопытно.
Dictionary<string, string> d = new Dictionary<string, string>();
d["a"] = "he";
d["ba"] = "llo";
d["lol"] = "world";
string a = string.Format("{a}{ba}{lol}", d);
Ответы
Ответ 1
Нет, но этот метод расширения сделает это
static string FormatFromDictionary(this string formatString, Dictionary<string, string> ValueDict)
{
int i = 0;
StringBuilder newFormatString = new StringBuilder(formatString);
Dictionary<string, int> keyToInt = new Dictionary<string,int>();
foreach (var tuple in ValueDict)
{
newFormatString = newFormatString.Replace("{" + tuple.Key + "}", "{" + i.ToString() + "}");
keyToInt.Add(tuple.Key, i);
i++;
}
return String.Format(newFormatString.ToString(), ValueDict.OrderBy(x => keyToInt[x.Key]).Select(x => x.Value).ToArray());
}
Ответ 2
Теперь возможно
С Interpolated Strings на С# 6.0 вы можете сделать это:
string name = "John";
string message = $"Hi {name}!";
//"Hi John!"
Ответ 3
Проверьте это, он поддерживает создание:
public static string StringFormat(string format, IDictionary<string, object> values)
{
var matches = Regex.Matches(format, @"\{(.+?)\}");
List<string> words = (from Match matche in matches select matche.Groups[1].Value).ToList();
return words.Aggregate(
format,
(current, key) =>
{
int colonIndex = key.IndexOf(':');
return current.Replace(
"{" + key + "}",
colonIndex > 0
? string.Format("{0:" + key.Substring(colonIndex + 1) + "}", values[key.Substring(0, colonIndex)])
: values[key].ToString());
});
}
Как использовать:
string format = "{foo} is a {bar} is a {baz} is a {qux:#.#} is a really big {fizzle}";
var dictionary = new Dictionary<string, object>
{
{ "foo", 123 },
{ "bar", true },
{ "baz", "this is a test" },
{ "qux", 123.45 },
{ "fizzle", DateTime.Now }
};
StringFormat(format, dictionary)
Ответ 4
Вы можете реализовать свои собственные:
public static string StringFormat(string format, IDictionary<string, string> values)
{
foreach(var p in values)
format = format.Replace("{" + p.Key + "}", p.Value);
return format;
}
Ответ 5
Фил Хаак обсудил несколько способов сделать это в своем блоге: http://haacked.com/archive/2009/01/14/named-formats-redux.aspx. Я использовал версию "Hanselformat" на двух проектах без каких-либо претензий.
Ответ 6
static public class StringFormat
{
static private char[] separator = new char[] { ':' };
static private Regex findParameters = new Regex(
"\\{(?<param>.*?)\\}",
RegexOptions.Compiled | RegexOptions.Singleline);
static string FormatNamed(
this string format,
Dictionary<string, object> args)
{
return findParameters.Replace(
format,
delegate(Match match)
{
string[] param = match.Groups["param"].Value.Split(separator, 2);
object value;
if (!args.TryGetValue(param[0], out value))
value = match.Value;
if ((param.Length == 2) && (param[1].Length != 0))
return string.Format(
CultureInfo.CurrentCulture,
"{0:" + param[1] + "}",
value);
else
return value.ToString();
});
}
}
Немного больше, чем другой метод расширения, но это также должно допускать использование нестроковых значений и шаблонов форматирования, поэтому в вашем исходном примере:
Dictionary<string, object> d = new Dictionary<string, object>();
d["a"] = DateTime.Now;
string a = string.FormatNamed("{a:yyyyMMdd-HHmmss}", d);
Будет также работать...
Ответ 7
Вот хорошее решение, которое очень полезно при форматировании писем: http://www.c-sharpcorner.com/UploadFile/e4ff85/string-replacement-with-named-string-placeholders/
Отредактировано:
public static class StringExtension
{
public static string Format( this string str, params Expression<Func<string,object>>[] args)
{
var parameters = args.ToDictionary( e=>string.Format("{{{0}}}",e.Parameters[0].Name), e=>e.Compile()(e.Parameters[0].Name));
var sb = new StringBuilder(str);
foreach(var kv in parameters)
{
sb.Replace( kv.Key, kv.Value != null ? kv.Value.ToString() : "");
}
return sb.ToString();
}
}
Пример использования:
public string PopulateString(string emailBody)
{
User person = _db.GetCurrentUser();
string firstName = person.FirstName; // Peter
string lastName = person.LastName; // Pan
return StringExtension.Format(emailBody.Format(
firstname => firstName,
lastname => lastName
));
}
Ответ 8
(ваш словарь + foreach + string.Replace), завернутый в подпрограмму или метод расширения?
Очевидно, неоптимизирован, но...