String.Format参数顺序烦恼

它真的很烦人C#似乎强迫你明确命名String.Format中每个参数的索引,如果你想在某个地方添加另一个参数,你必须重新索引字符串或将新参数放在最后。

有没有办法让C#自动执行此操作?

例如(我知道这是毫无意义的小贩,这只是一个例子:)

我从:

String.Format("{0} {1} {1} {2} {3}", a, b, c, d) 

如果我想在开头添加一个参数,我可以执行以下操作之一:

 String.Format("{4} {0} {1} {1} {2} {3}", a, b, c, d, e) String.Format("{0} {1} {2} {2} {3} {4}", e, a, b, c, d) 

以Delphi为例,我可以做到相当于:

 String.Format("{} {} {} {2} {} {}", e, a, b, c, d) 

好吧,C#中没有任何内容可以自动为您执行此操作。 你总是可以编写自己的方法来做到这一点,但坦率地说,我发现它的可读性较差。 还有很多事情要做(IMO)来理解你的最后一行比前一行更好。 当你点击{2}你必须在精神上回溯并用{3}替换前一项以跳过{2}等。

就个人而言,我更喜欢需要更长时间输入的代码,但是读起来很清楚。

从Visual Studio 2015开始,您可以使用Interpolated Strings (它是一个编译器技巧)来解决这个问题,因此您定位的.net框架版本无关紧要。

然后代码看起来像这样

 string txt = $"{person.ForeName} is not at home {person.Something}"; 

我认为它使代码更易读,更不容易出错。

您请求的function不是框架的一部分。 这是一个很好的扩展方法,我发现它提供了命名参数c#。 我认为Marc Gravell发布了它或其他一些SO大师。

  static readonly Regex rePattern = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled); ///  /// Shortcut for string.Format. Format string uses named parameters like {name}. /// /// Example: /// string s = Format("{age} years old, last name is {name} ", new {age = 18, name = "Foo"}); /// ///  ///  ///  ///  public static string FN(this string pattern, T template) { Dictionary cache = new Dictionary(); return rePattern.Replace(pattern, match => { string key = match.Groups[1].Value; string value; if (!cache.TryGetValue(key, out value)) { var prop = typeof(T).GetProperty(key); if (prop == null) { throw new ArgumentException("Not found: " + key, "pattern"); } value = Convert.ToString(prop.GetValue(template, null)); cache.Add(key, value); } return value; }); } 

尽管C#不能为您做到这一点,但该工具可以为您提供帮助。

例如,如果字符串中的参数多于字符串后面的参数,则Resharper会发出警告。 我看看是否支持Resharper中的参数重新排序,但在这种情况下它不是(R#支持更改方法签名,但这对此没有帮助)。

看看DevEx的Code Rush。 该工具很可能具备您的需求。

我知道这是旧的,我同意乔恩。 即使使用大格式字符串(参见下面的代码示例),如果我必须添加一些内容,重新启动项目的索引位置仍然只需要不到1分钟,我发现它更易于维护和读取,然后尝试创建一个自动化过程的方法。 自动化的问题在于,几周后我试着查看代码……你不能只是乍看之下。 此外,一旦您熟悉Visual Studio并学习使用块编辑模式和其他一些高级function,您就可以非常高效。

 //----------------------------------------------------------------------------- //  // Copyright (c) DCOM Productions. All rights reserved. //  //----------------------------------------------------------------------------- string updateCommandText = string.Format("UPDATE `moh`.`moh` SET ageact = '{0}', branch = '{1}', cemetary = '{2}', citation = '{3}', citycement = '{4}', cdateact = '{5}', cdateaward = '{6}', cdatebirth = '{7}', cdatedeath = '{8}', namefirst = '{9}', namelast = '{10}', placeact = '{11}', placeenter = '{12}', presat = '{13}', presby = '{14}', rankact = '{15}', rankawd = '{16}', rankhigh = '{17}', synopsis = '{18}', unit = '{19}', war = '{20}', imgfile = '{21}' WHERE ID = '{22}'", /* {0} */ uxAgeAct.Text.Replace("'", "''"), /* {1} */ uxBranch.Text.Replace("'", "''"), /* {2} */ uxCemetary.Text.Replace("'", "''"), /* {3} */ uxCitation.Text.Replace("'", "''"), /* {4} */ uxCityCemetary.Text.Replace("'", "''"), /* {5} */ uxDateAct.Text.Replace("'", "''"), /* {6} */ uxDateAward.Text.Replace("'", "''"), /* {7} */ uxDateBirth.Text.Replace("'", "''"), /* {8} */ uxDateDiceased.Text.Replace("'", "''"), /* {9} */ uxNameFirst.Text.Replace("'", "''"), /* {10} */ uxNameLast.Text.Replace("'", "''"), /* {11} */ uxPlaceAct.Text.Replace("'", "''"), /* {12} */ uxPlaceEnter.Text.Replace("'", "''"), /* {13} */ uxPresentedAt.Text.Replace("'", "''"), /* {14} */ uxPresentedBy.Text.Replace("'", "''"), /* {15} */ uxRankAct.Text.Replace("'", "''"), /* {16} */ uxRankAwarded.Text.Replace("'", "''"), /* {17} */ uxRankHigh.Text.Replace("'", "''"), /* {18} */ uxSynopsis.Text.Replace("'", "''"), /* {19} */ uxUnit.Text.Replace("'", "''"), /* {20} */ uxWar.Text.Replace("'", "''"), /* {21} */ uxImgFile.Text.Replace("'", "''"), /* {22} */ dataRow["ID"].ToString());