C# 格式参数顺序烦恼

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,

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, 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:这没有解决问题