Можно ли включить переменную С# в строковую переменную без использования конкатенатора?
Позволяет ли .NET 3.5 С# включать переменную в строковую переменную без использования + concatenator (или string.Format(), если на то пошло).
Например (в псевдо, я использую символ $для указания переменной):
DateTime d = DateTime.Now;
string s = "The date is $d";
Console.WriteLine(s);
Вывод:
Дата 4/12/2011 11:56:39 AM
Edit
Из-за нескольких ответов, которые предложили string.Format(), я могу только предположить, что мой оригинальный пост не был ясен, когда я упомянул "... (или string.Format(), если на то пошло)". Чтобы быть ясным, я хорошо знаю метод string.Format(). Однако в моем конкретном проекте, над которым я работаю, string.Format() не помогает мне (это на самом деле хуже, чем + конкатенатор).
Кроме того, я предполагаю, что большинство/все вы задаетесь вопросом, каков мотив моего вопроса (я полагаю, что я буду чувствовать то же самое, если бы я прочитал свой вопрос так, как есть).
Если вы один из любопытных, здесь коротко:
Я создаю веб-приложение, работающее на устройстве Windows CE. Благодаря тому, как работает веб-сервер, я создаю содержимое всей веб-страницы (css, js, html и т.д.) В строковой переменной. Например, мой управляемый код .cs может иметь что-то вроде этого:
string GetPageData()
{
string title = "Hello";
DateTime date = DateTime.Now;
string html = @"
<!DOCTYPE html PUBLIC ...>
<html>
<head>
<title>$title</title>
</head>
<body>
<div>Hello StackO</div>
<div>The date is $date</div>
</body>
</html>
";
}
Как вы можете видеть, наличие возможности указывать переменную без необходимости конкатенации делает вещи немного проще - особенно когда контент увеличивается в размере.
Ответы
Ответ 1
Почти, с небольшим методом расширения.
static class StringExtensions
{
public static string PHPIt<T>(this string s, T values, string prefix = "$")
{
var sb = new StringBuilder(s);
foreach(var p in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
sb = sb.Replace(prefix + p.Name, p.GetValue(values, null).ToString());
}
return sb.ToString();
}
}
И теперь мы можем написать:
string foo = "Bar";
int cool = 2;
var result = "This is a string $foo with $cool variables"
.PHPIt(new {
foo,
cool
});
//result == "This is a string Bar with 2 variables"
Ответ 2
Нет, к сожалению, С# не является PHP.
Однако на яркой стороне С# не является PHP.
Ответ 3
Нет, это не так. Есть способы обойти это, но они побеждают цель. Самая простая вещь для вашего примера -
Console.WriteLine("The date is {0}", DateTime.Now);
Ответ 4
string output = "the date is $d and time is $t";
output = output.Replace("$t", t).Replace("$d", d); //and so on
Ответ 5
Основываясь на большом ответе @JesperPalm, я нашел еще одно интересное решение, которое позволяет использовать аналогичный синтаксис, как в обычном методе string.Format
:
public static class StringExtensions
{
public static string Replace<T>(this string text, T values)
{
var sb = new StringBuilder(text);
var properties = typeof(T)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToArray();
var args = properties
.Select(p => p.GetValue(values, null))
.ToArray();
for (var i = 0; i < properties.Length; i++)
{
var oldValue = string.Format("{{{0}", properties[i].Name);
var newValue = string.Format("{{{0}", i);
sb.Replace(oldValue, newValue);
}
var format = sb.ToString();
return string.Format(format, args);
}
}
Это дает вам возможность добавить обычное форматирование:
var hello = "Good morning";
var world = "Mr. Doe";
var s = "{hello} {world}! It is {Now:HH:mm}."
.Replace(new { hello, world, DateTime.Now });
Console.WriteLine(s); // -> Good morning Mr. Doe! It is 13:54.
Ответ 6
Короткий и простой ответ: No!
Ответ 7
string.Format("The date is {0}", DateTime.Now.ToString())
Ответ 8
Нет, но вы можете создать метод расширения для экземпляра строки, чтобы сделать типизацию короче.
string s = "The date is {0}".Format(d);
Ответ 9
string.Format
(и аналогичные функции форматирования, такие как StringBuilder.AppendFormat
), - лучший способ сделать это с точки зрения гибкости, практики кодирования и (обычно) производительности:
string s = string.Format("The date is {0}", d);
Вы также можете указать формат отображения вашего DateTime, а также вставить в строку более одного объекта. Проверьте страницу MSDN в методе string.Format.
Некоторые типы также имеют перегрузки для своих методов ToString
, которые позволяют указать строку формата. Вы также можете создать метод расширения для string
, который позволяет указать формат и/или синтаксический синтаксический анализ, подобный этому.
Ответ 10
Как насчет использования механизма моделирования T4?
http://visualstudiomagazine.com/articles/2009/05/01/visual-studios-t4-code-generation.aspx
Ответ 11
Если вы просто пытаетесь избежать конкатенации неизменяемых строк, то вы ищете StringBuilder.
Использование:
string parameterName = "Example";
int parameterValue = 1;
Stringbuilder builder = new StringBuilder();
builder.Append("The output parameter ");
builder.Append(parameterName);
builder.Append(" value is ");
builder.Append(parameterValue.ToString());
string totalExample = builder.ToString();
Ответ 12
Так как С# 6.0 вы можете написать строку "The title is \{title}"
, которая делает именно то, что вам нужно.
Ответ 13
Или комбинированный:
Console.WriteLine("The date is {0}", DateTime.Now);
Дополнительная информация (в ответ на BrandonZeider):
Да, это хорошо - важно, чтобы люди поняли, что преобразование строк выполняется автоматически. Ручное добавление ToString нарушено, например:
string value = null;
Console.WriteLine("The value is '{0}'", value); // OK
Console.WriteLine("The value is '{0}'", value.ToString()); // FAILURE
Кроме того, это становится намного менее тривиальным, если вы понимаете, что строковое кодирование не эквивалентно использованию .ToString(). У вас могут быть спецификаторы форматирования и даже пользовательские форматные поставщики... Это достаточно интересно, чтобы научить людей использовать String.Format вместо того, чтобы делать это вручную.