简体   繁体   English

等效的string.Format,不会使用额外的标记引发异常

[英]string.Format equivalent that doesn't throw exception with extra marker

I want end user of my application to edit format string that is used in string.Format . 我希望应用程序的最终用户编辑在string.Format使用的格式字符串。 I want to do that to give user ability to edit templates. 我想这样做是为了让用户能够编辑模板。 Problem occurs when user enters too much markers. 当用户输入太多标记时,会发生问题。

This works fine: 这工作正常:

var result = string.Format("test {0}, {1}, {2}", 1, 2, 3);

this works too: 这也适用:

var result = string.Format("test {0}, {1}", 1, 2, 3);

but this throws exception: 但这会引发异常:

var result = string.Format("test {0}, {1}, {2}", 1, 2);

System.FormatException: 'Index (zero based) must be greater than or equal to zero and less than the size of the argument list.' System.FormatException:'索引(从零开始)必须大于或等于零且小于参数列表的大小。

I'm aware that I must add as much parameters as there are markers, but end user don't know that, or he can make mistakes - add extra marker. 我知道我必须添加和标记一样多的参数,但是最终用户不知道这些,否则他可能会犯错误-添加额外的标记。

My question is: 我的问题是:
Can I use similar approach to format string in a way string.Format works but without exception. 我可以使用类似的方法以string.Format工作的方式格式化字符串,但没有例外。

I know I could use try\\catch block and return format string, but I don't want to do that. 我知道我可以使用try\\catch块并返回格式字符串,但是我不想这样做。

I've build very simple method that replace markers in string: 我建立了一个非常简单的方法来替换字符串中的标记:

public static string SafeFormat(string format, params object[] args)
{
    var result = format;
    for (int i = 0; i < args.Length; i++)
    {
        result = result.Replace($"{{{i}}}", args[i].ToString());
    }
    return result;
}

but this isn't supporting formatting of data that is used in place of markers. 但这不支持用来代替标记的数据格式。

Internally string.Format is using AppendFormatHelper ( http://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,2c3b4c2e7c43f5a4 ) that is more complex than my simple replace. 在内部, string.Format使用的AppendFormatHelperhttp://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,2c3b4c2e7c43f5a4 )比我的简单替换要复杂。

Ideally string.Format("test {0}, {1}, {2}", 1, 2) should return test 1, 2, {2} 理想情况下, string.Format("test {0}, {1}, {2}", 1, 2)应该返回test 1, 2, {2}

One solution is to check how many values are expected, and just append others to argument list (null or placeholders). 一种解决方案是检查期望有多少个值,然后将其他值附加到参数列表(空值或占位符)。 Example string extension: 字符串扩展示例:

public static class StringExtensions
{
    public static string SafeFormat(this string value, params object[] args)
    {
        var pattern = @"{(.*?)}";
        var matches = Regex.Matches(value, pattern);
        var matchCount = matches.Count;
        if (matchCount > args.Length)
        {
            var argsExtended = args.ToList();
            for (int i = args.Length; i < matchCount; i++)
            {
                argsExtended.Add($"{{{i}}}"); //Can add null value to erase them
            }
            return string.Format(value, argsExtended.ToArray());
        }
        return string.Format(value, args);
    }
}

You can easily change this to method if you want 您可以根据需要轻松地将其更改为方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM