假设我有一个这样的FormattableString:
var now = DateTime.Now;
FormattableString str = $"Today's date is: {now:yyyy-MM-dd} and some numbers: {new[]{1,2,3}}";我正在尝试获取一个可格式化字符串并将其转换为用于另一个组件中。在我的例子中,实际上是在值处分割格式字符串,这样我就可以控制它们是如何连接回的,但是我需要参数的格式字符串。
在FormattableString上有一些有限的方法,允许我获取参数值(GetArguments()/GetArgument())和原始格式字符串(Format),但是没有一个用于访问参数格式化字符串。
var format = str.Format; // "Today's date is: {0:yyyy-MM-dd} and some numbers: {1}"
var arguments = str.GetArguments(); // { now, new[]{1,2,3} }
// no simple way to get the "yyyy-MM-dd" part for arg 0我正在寻找的解决办法是预先格式化该值,以便将格式化的值设置为参数或解析出格式字符串,这是不理想的。
void DumpLine(FormattableString format)
{
var values = format.GetArguments().Prepend(null);
var parts = Regex.Split(format.Format, @"\{[^}]+\}");
Util.HorizontalRun(false, values.Zip(parts).SelectMany(x => new[] { x.First, x.Second }).Skip(1)).Dump();
}
// usage
DumpLine($"Today's date is: {now.ToString("yyyy-MM-dd")} and some numbers: {new[]{1,2,3}}");这是支持的,也许是通过一个助手类,还是我运气不好?
感谢mariusz96指出了新的InterpolatedStringHandler功能。对我来说正是我所需要的。它甚至足够灵活,如果我将来需要的话,可以添加额外的参数。这就是我最后的结局:
public static class UtilEx
{
public static object Interpolate(IFormatProvider provider, [InterpolatedStringHandlerArgument(nameof(provider))] InterpolateFormatHandler handler) => Interpolate(handler);
public static object Interpolate(InterpolateFormatHandler handler) => Util.HorizontalRun(false, handler.Items);
[InterpolatedStringHandler]
public ref struct InterpolateFormatHandler
{
private readonly IFormatProvider? provider;
public InterpolateFormatHandler(int _literalLength, int _formattedCount, IFormatProvider? provider = default) => this.provider = provider;
public List<object?> Items { get; } = new();
public void AppendLiteral(string s) => Items.Add(s);
public void AppendFormatted<T>(T t, int alignment, string format) => Items.Add(string.Format(provider, $"{{0,{alignment}:{format}}}", t));
public void AppendFormatted<T>(T t, int alignment) => Items.Add(string.Format(provider, $"{{0,{alignment}}}", t));
public void AppendFormatted<T>(T t, string format) => Items.Add(string.Format(provider, $"{{0:{format}}}", t));
public void AppendFormatted<T>(T t) => Items.Add(t);
}
}发布于 2022-08-30 13:18:00
这在定制的InterpolatedStringHandler中是可能的。
它有过载,需要对齐和格式化。
https://stackoverflow.com/questions/71005770
复制相似问题