10

.NET 3.5 C# 是否允许我们在字符串变量中包含一个变量,而不必使用 + 连接符(或 string.Format(),就此而言)。

例如(在伪中,我使用 $ 符号来指定变量):

DateTime d = DateTime.Now;
string s = "The date is $d";
Console.WriteLine(s);

输出:

日期是 2011 年 4 月 12 日上午 11:56:39

编辑

由于建议 string.Format() 的响应很少,我只能假设当我提到“ ...(或 string.Format(),就此而言) ”时,我的原始帖子并不清楚。需要明确的是,我很清楚 string.Format() 方法。但是,在我正在处理的特定项目中, string.Format() 对我没有帮助(它实际上比 + 连接器更糟糕)。

另外,我推断你们中的大多数/所有人都想知道我的问题背后的动机是什么(我想如果我按原样阅读我的问题,我会有同样的感觉)。

如果你是好奇者之一,这里是它的短处:

我正在创建一个在 Windows CE 设备上运行的 Web 应用程序。由于 Web 服务器的工作方式,我在一个字符串变量中创建了整个网页内容(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>
    ";

}

正如您所看到的,能够指定变量而无需连接,这让事情变得更容易——尤其是当内容的大小增加时。

4

14 回答 14

12

不,不幸的是 C# 不是 PHP。
不过,从好的方面来说,C# 不是 PHP。

于 2011-04-12T19:06:13.737 回答
8

差不多,用一个小的扩展方法。

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"
于 2011-04-12T20:38:00.847 回答
3

不,它没有。有一些方法可以解决这个问题,但它们破坏了目的。你的例子最简单的事情是

Console.WriteLine("The date is {0}", DateTime.Now);
于 2011-04-12T19:02:34.007 回答
3
string output = "the date is $d and time is $t";
output = output.Replace("$t", t).Replace("$d", d);  //and so on
于 2011-04-12T19:03:27.077 回答
3

string.Format基于@JesperPalm 的出色回答,我找到了另一个有趣的解决方案,它让您可以使用与普通方法类似的语法:

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.
于 2014-05-08T11:56:21.297 回答
2

简短而简单的答案是:不!

于 2011-04-12T19:04:56.177 回答
0
string.Format("The date is {0}", DateTime.Now.ToString())
于 2011-04-12T19:02:32.850 回答
0

不,但是您可以在字符串实例上创建扩展方法以缩短键入时间。

string s = "The date is {0}".Format(d);
于 2011-04-12T19:05:48.400 回答
0

string.Format(以及类似的格式化函数,例如StringBuilder.AppendFormat)在灵活性、编码实践和(通常)性能方面是做到这一点的最佳方式:

string s = string.Format("The date is {0}", d);

您还可以指定 DateTime 的显示格式,以及在字符串中插入多个对象。查看MSDN 关于 string.Format 方法的页面

某些类型的ToString方法也有重载,允许您指定格式字符串。您还可以创建一个扩展方法string,允许您像这样指定格式和/或解析语法。

于 2011-04-12T19:06:36.420 回答
0

使用 T4 模板引擎怎么样?

http://visualstudiomagazine.com/articles/2009/05/01/visual-studios-t4-code-generation.aspx

于 2011-04-12T19:43:02.963 回答
0

如果您只是想避免连接不可变字符串,那么您正在寻找的是StringBuilder

用法:

string parameterName = "Example";
int parameterValue = 1;
Stringbuilder builder = new StringBuilder();
builder.Append("The output parameter ");
builder.Append(parameterName);
builder.Append("'s value is ");
builder.Append(parameterValue.ToString());
string totalExample = builder.ToString();
于 2011-04-12T20:37:45.453 回答
0

C# 6.0 开始,您可以编写"The title is \{title}"完全符合您需要的字符串。

于 2014-12-01T13:08:25.660 回答
0

您可以使用 C# 文档中提到的类似内容。 字符串插值

string name = "Horace";
int age = 34;
Console.WriteLine($"He asked, \"Is your name {name}?\", but didn't wait for a reply :-{{");
Console.WriteLine($"{name} is {age} year{(age == 1 ? "" : "s")} old.");
于 2020-06-21T14:43:01.457 回答
-1

或组合:

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 而不是手动操作,这很有趣。

于 2011-04-12T19:04:24.727 回答