C# 格式参数顺序烦恼
C#似乎强迫您以String.Format显式命名每个参数的索引,这真是令人恼火。如果您想在某个地方添加另一个参数,您必须重新为字符串编制索引或将新参数放在末尾 有没有办法让C#自动做到这一点 e、 (我知道这是毫无意义的书呆子,这只是一个例子:) 我首先说:C# 格式参数顺序烦恼,c#,string,formatting,C#,String,Formatting,C#似乎强迫您以String.Format显式命名每个参数的索引,这真是令人恼火。如果您想在某个地方添加另一个参数,您必须重新为字符串编制索引或将新参数放在末尾 有没有办法让C#自动做到这一点 e、 (我知道这是毫无意义的书呆子,这只是一个例子:) 我首先说: String.Format("{0} {1} {1} {2} {3}", a, b, c, d) 如果要在开头添加参数,可以执行以下操作之一: String.Format("{4} {0} {1} {1} {2} {3}", a, b,
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语言中没有任何东西可以自动为您执行此操作。你可以写你自己的方法来做这件事,但坦率地说,我觉得它不太可读。在我看来,要理解你的最后一行比前一行要做的事情要多得多。当你点击{2}
时,你必须在心理上回溯并用{3}
替换上一项,以跳过{2}
等
就我个人而言,我更喜欢键入时间稍长,但易于阅读的代码。您请求的函数不是框架的一部分。我发现了一个很好的扩展方法,它提供了命名参数c#。我想是马克·格雷威尔贴的,或者是其他大师的作品
static readonly Regex rePattern = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled);
/// <summary>
/// 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"});
///
/// </summary>
/// <param name="format"></param>
/// <param name="values"></param>
/// <returns></returns>
public static string FN<T>(this string pattern, T template)
{
Dictionary<string, string> cache = new Dictionary<string, string>();
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;
});
}
static readonly Regex rePattern=newregex(@“\{([^\}]+)\}”,RegexOptions.Compiled);
///
///string.Format的快捷方式。格式化字符串使用命名参数,如{name}。
///
///例如:
///字符串s=格式(“{age}岁,姓{name}”,新的{age=18,name=“Foo”});
///
///
///
///
///
公共静态字符串FN(此字符串模式,T模板)
{
字典缓存=新字典();
返回rePattern.Replace(模式,匹配=>
{
字符串键=匹配。组[1]。值;
字符串值;
如果(!cache.TryGetValue(键,输出值))
{
var prop=typeof(T).GetProperty(key);
if(prop==null)
{
抛出新的ArgumentException(“找不到:+key,“pattern”);
}
value=Convert.ToString(prop.GetValue(模板,null));
cache.Add(键、值);
}
返回值;
});
}
即使C#无法为您执行此操作,该工具在这里也会有所帮助
例如,如果字符串中的参数多于字符串后面的参数,Resharper会发出警告。我查看了Resharper中的参数重新排序是否受支持,但在本例中不受支持(R#支持更改方法签名,但在这里没有帮助)
看看来自DevEx的代码流。这个工具很可能有你所需要的。我知道这个很旧,我同意乔恩的观点。即使使用大格式字符串(参见下面的代码示例),如果我必须添加一些内容,我仍然只需要不到1分钟的时间就可以重做项目的索引位置,并且我发现它更易于维护和可读,然后尝试创建一种方法来自动化该过程。这方面的自动化问题是,几周后我试图查看代码。。你不能一眼就看懂。此外,一旦您学好VisualStudio并学会使用诸如块编辑模式和其他一些高级功能,您就可以非常高效
//-----------------------------------------------------------------------------
// <copyright file="ShellForm.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
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());
//-----------------------------------------------------------------------------
//
//版权所有(c)DCOM产品。版权所有。
//
//-----------------------------------------------------------------------------
string updateCommandText=string.Format(“UPDATE`moh`.`moh`SET ageact='{0}',branch='{1}',cemetary='{2}',引文='{3}',citycement='{4}',cdateact='{5}',cdateaward='{6}',cdatebirth='{7}',cdatedeath='{8}',namefirst='{9}',namelast='{10}',placeact='{11}',placeact=''{12',placepresat13}{“,rankact='{15}',rankawd='{16}',rankhigh='{17}',大纲='{18}',单元='{19}',战争='{20}',imgfile='{21}',其中ID='{22}',
/*{0}*/uxAgeAct.Text.Replace(“,”),
/*{1}*/uxBranch.Text.Replace(“,”),
/*{2}*/uxCemetary.Text.Replace(“,”),
/*{3}*/uxCitation.Text.Replace(“,”),
/*{4}*/uxCityMetary.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}*/uxplacenter.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();
从VisualStudio2015开始,您可以使用(这是一个编译器技巧,所以您针对的是.net framework的哪个版本并不重要)来回避此问题
代码如下所示
string txt = $"{person.ForeName} is not at home {person.Something}";
我认为它使代码更具可读性,更不容易出错。+1:在最初编写代码时,可维护性应始终胜过一次性的节省。+1“计算机程序应设计为供人阅读,并由计算机偶然运行”String.Format({a}{b}{b}{c}{d}),a,b,c,d)如何?这可以添加到.NET4.0中吗?也许编译器能帮上忙。还是新的DLR?我可能在这里漏掉了一些东西,但这会很好…通过将参数放在下一行来解决可读性问题。@Jamie:这没有解决问题