String、FormattableString、IFormattable 之间的区别
Difference between String, FormattableString, IFormattable
FormattableString
已在 C# 6.0 中引入。因为我们可以使用 string
对象使用相同的字符串格式,所以为什么需要使用 FormattableString
或 IFormattable
。三者有什么区别?
我的代码
var name = "Pravin";
var s = $"Hello, {name}";
System.IFormattable s1 = $"Hello, {name}";
System.FormattableString s2 = $"Hello, {name}";
最重要的是产生相同的结果。即 'Hello Pravin'.
如果有人对此有深入的了解,我能得到更详细的答案吗?
FormattableString
是.NET 4.6中的一个新类型,编译器只有在你尝试使用它的情况下才会使用它。换句话说,内插字符串文字的类型通常是 string
- 用 string.Format
构建 - 但如果你要求的话可以是 FormattableString
(通过 FormattableStringFactory
)。
A FormattableString
由将传递给 string.Format
(例如 "Hello, {0}"
)的格式字符串和为了格式化它而传递的参数组成。至关重要的是,此信息是在 格式化之前 捕获的。
这允许您适当地调整格式 - 最常见的是在不变文化中执行它,通常使用 Invariant
static method。
当您将内插字符串文字分配给 IFormattable
变量时,也会使用 FormattableString
。 IFormattable.ToString(string, CultureInfo)
implementation 在这种情况下忽略了第一个参数,这大概就是它使用显式接口实现的原因。
示例代码:
using System;
using System.Globalization;
using System.Threading;
using static System.FormattableString;
class Test
{
static void Main()
{
var uk = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = uk;
var germany = CultureInfo.CreateSpecificCulture("de-DE");
string now = $"Default: it is now {DateTime.UtcNow}";
Console.WriteLine(now); // UK format
IFormattable x = $"Specific: It is now {DateTime.UtcNow}";
Console.WriteLine(x.ToString("ignored", germany));
FormattableString y = $"FormattableString: It is now {DateTime.UtcNow}";
Console.WriteLine(FormattableString.Invariant(y));
// Via using static
Console.WriteLine(Invariant($"It is now {DateTime.UtcNow}"));
}
}
示例结果:
Default: it is now 16/02/2016 07:16:21
Specific: It is now 16.02.2016 07:16:21
FormattableString: It is now 02/16/2016 07:16:21
It is now 02/16/2016 07:16:21
顺便说一句,https://www.meziantou.net/interpolated-strings-advanced-usages.htm 涵盖了 FormattableString 允许您执行的操作的一些示例(例如自动参数化 SQL 语句)
例如
void ExecuteNonQuery(DbConnection connection, FormattableString formattableString)
{
using (var command = connection.CreateCommand())
{
// Replace values by @p0, @p1, @p2, ....
var args = Enumerable.Range(0, formattableString.ArgumentCount).Select(i => (object)("@p" + i)).ToArray();
command.CommandType = System.Data.CommandType.Text;
command.CommandText = string.Format(formattableString.Format, args);
// Create parameters
for (var i = 0; i < formattableString.ArgumentCount; i++)
{
var arg = formattableString.GetArgument(i);
var p = command.CreateParameter();
p.ParameterName = "@p" + i;
p.Value = arg;
command.Parameters.Add(p);
}
// Execute the command
command.ExecuteNonQuery();
}
}
using (var sqlConnection = new SqlConnection())
{
sqlConnection.Open();
ExecuteNonQuery(sqlConnection, $@"UPDATE Customers SET Name = {"Meziantou"} WHERE Id = {1}");
}
FormattableString
已在 C# 6.0 中引入。因为我们可以使用 string
对象使用相同的字符串格式,所以为什么需要使用 FormattableString
或 IFormattable
。三者有什么区别?
我的代码
var name = "Pravin";
var s = $"Hello, {name}";
System.IFormattable s1 = $"Hello, {name}";
System.FormattableString s2 = $"Hello, {name}";
最重要的是产生相同的结果。即 'Hello Pravin'.
如果有人对此有深入的了解,我能得到更详细的答案吗?
FormattableString
是.NET 4.6中的一个新类型,编译器只有在你尝试使用它的情况下才会使用它。换句话说,内插字符串文字的类型通常是 string
- 用 string.Format
构建 - 但如果你要求的话可以是 FormattableString
(通过 FormattableStringFactory
)。
A FormattableString
由将传递给 string.Format
(例如 "Hello, {0}"
)的格式字符串和为了格式化它而传递的参数组成。至关重要的是,此信息是在 格式化之前 捕获的。
这允许您适当地调整格式 - 最常见的是在不变文化中执行它,通常使用 Invariant
static method。
当您将内插字符串文字分配给 IFormattable
变量时,也会使用 FormattableString
。 IFormattable.ToString(string, CultureInfo)
implementation 在这种情况下忽略了第一个参数,这大概就是它使用显式接口实现的原因。
示例代码:
using System;
using System.Globalization;
using System.Threading;
using static System.FormattableString;
class Test
{
static void Main()
{
var uk = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = uk;
var germany = CultureInfo.CreateSpecificCulture("de-DE");
string now = $"Default: it is now {DateTime.UtcNow}";
Console.WriteLine(now); // UK format
IFormattable x = $"Specific: It is now {DateTime.UtcNow}";
Console.WriteLine(x.ToString("ignored", germany));
FormattableString y = $"FormattableString: It is now {DateTime.UtcNow}";
Console.WriteLine(FormattableString.Invariant(y));
// Via using static
Console.WriteLine(Invariant($"It is now {DateTime.UtcNow}"));
}
}
示例结果:
Default: it is now 16/02/2016 07:16:21
Specific: It is now 16.02.2016 07:16:21
FormattableString: It is now 02/16/2016 07:16:21
It is now 02/16/2016 07:16:21
顺便说一句,https://www.meziantou.net/interpolated-strings-advanced-usages.htm 涵盖了 FormattableString 允许您执行的操作的一些示例(例如自动参数化 SQL 语句)
例如
void ExecuteNonQuery(DbConnection connection, FormattableString formattableString)
{
using (var command = connection.CreateCommand())
{
// Replace values by @p0, @p1, @p2, ....
var args = Enumerable.Range(0, formattableString.ArgumentCount).Select(i => (object)("@p" + i)).ToArray();
command.CommandType = System.Data.CommandType.Text;
command.CommandText = string.Format(formattableString.Format, args);
// Create parameters
for (var i = 0; i < formattableString.ArgumentCount; i++)
{
var arg = formattableString.GetArgument(i);
var p = command.CreateParameter();
p.ParameterName = "@p" + i;
p.Value = arg;
command.Parameters.Add(p);
}
// Execute the command
command.ExecuteNonQuery();
}
}
using (var sqlConnection = new SqlConnection())
{
sqlConnection.Open();
ExecuteNonQuery(sqlConnection, $@"UPDATE Customers SET Name = {"Meziantou"} WHERE Id = {1}");
}