首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >给定一个可格式化字符串,是否有一种干净的方法来获取给定参数的格式化字符串?

给定一个可格式化字符串,是否有一种干净的方法来获取给定参数的格式化字符串?
EN

Stack Overflow用户
提问于 2022-02-06 09:23:58
回答 1查看 475关注 0票数 2

假设我有一个这样的FormattableString

代码语言:javascript
复制
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),但是没有一个用于访问参数格式化字符串。

代码语言:javascript
复制
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

我正在寻找的解决办法是预先格式化该值,以便将格式化的值设置为参数或解析出格式字符串,这是不理想的。

代码语言:javascript
复制
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功能。对我来说正是我所需要的。它甚至足够灵活,如果我将来需要的话,可以添加额外的参数。这就是我最后的结局:

代码语言:javascript
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-30 13:18:00

这在定制的InterpolatedStringHandler中是可能的。

它有过载,需要对齐和格式化。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71005770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档