6

我想做这样的事情:

public string GetMessage(params object otherValues[]) {
    return String.Format(this.Message, this.FirstValue, otherValues);
}

所以,我想重新传递一个参数数组,String.Format()但添加一个新参数。

最好的方法是什么,知道我们可以“重建”一个新的对象数组,这似乎并不好。

4

6 回答 6

17
public string GetMessage(params object[] otherValues)
{
    return String.Format(this.Message, new[] { this.FirstValue }.Concat(otherValues).ToArray<object>());
}
于 2012-05-08T17:45:44.243 回答
3

您可以使用ConcatandToArray扩展方法:

public string GetMessage(params object[] otherValues) 
{
    var values = new[] { this.FirstName }.Concat(otherValues).ToArray();
    return String.Format(this.Message, values);
}
于 2012-05-08T17:43:04.727 回答
1

如果other参数通常很少,我会使用现有的重载:

public string GetMessage(params object[] otherValues) {
    if (otherValues == null) return string.Format(this.Message, this.FirstValue);

    switch (otherValues.Length)
    {
        case 0:
            return string.Format(this.Message, this.FirstValue);
        case 1:
            return string.Format(this.Message, this.FirstValue, otherValues[0]);
        case 2:
            return string.Format(this.Message, this.FirstValue, otherValues[0], otherValues[1]);
        default:
            return string.Format(this.Message, new[] { this.FirstValue }.Concat(otherValues).ToArray()); 
    }
}
于 2012-05-08T17:58:32.347 回答
1

预处理消息

如果您不想在每个GetMessage(...)调用中创建一个新数组,您可以在开始时FirstValue插入Message中一次。然后GetMessage(...)只使用string.Format(...)的otherValues参数。

Message属性在设置 FirstValue 后初始化一次,例如在构造函数或 init 方法中,如下所示:

void InitMessage()
{
    Message = String.Format(Message, FirstValue, "{0}", "{1}", "{2}", "{3}", "{4}");
}

InitMessage方法用 FirstValue 初始化 Message 中的第一个索引,用{ index }”初始化其余索引,即“{0}”、“{1}”、“{2}”、...(允许有比消息索引更多的元素)。 params

现在GetMessage可以调用String.Format而无需像这样的任何数组操作:

public string GetMessage(params object[] otherValues)
{
  return String.Format(Message, otherValues);
}

例子:

假设以下属性值:
this.Message = "First value is '{0}'. Other values are '{1}' and '{2}'."this.FirstValue = "blue"

InitMessageMessage更改为:
"First value is 'blue'. Other values are '{0}' and '{1}'."

GetMessage调用
GetMessage("green", "red")

结果
"First value is 'blue'. Other values are 'green' and 'red'."

于 2012-05-08T19:30:32.880 回答
0

如果您真的无法为数组创建另一个结构,另一种混乱的方法是使用 RegEx 破解您的格式。

private string FormatEval(Match m)
{
    int val = -1;
    string formatted = m.Value;
    if (int.TryParse(m.Groups["index"].Value, out val))
        formatted = val == 0 ? this.FirstValue : "{" + (val - 1).ToString() + "}";
    return formatted;
}

public string GetMessage(params object[] otherValues)
{
    string format = Regex.Replace(this.Message, @"\{(?<index>\d+)\}", FormatEval);
    return string.Format(format, otherValues);
}

基本上只需解析格式化标记({0}、{1})等的格式字符串,并减少它们的索引。如果令牌最初是 {0},请将其替换为 this.FirstName 字符串。

本质上,这是在手动执行 String.Format 的第一步,然后将生成的字符串传递给 REAL String.Format 方法以完成。

于 2012-05-10T07:04:10.183 回答
0

传递离散元素

为了避免在everey GetMessage调用中创建数组,您可以通过其离散元素传递otherValues :

public string GetMessage(params object[] otherValues)
{
  return String.Format(Message,
                       FirstValue,
                       GetOrDefault(otherValues, 0),
                       GetOrDefault(otherValues, 1),
                       GetOrDefault(otherValues, 2),
                       GetOrDefault(otherValues, 3),
                       GetOrDefault(otherValues, 4));
}

private object GetOrDefault(object[] otherValues, int index)
{
  if (otherValues == null)
    return null;

  if (index < otherValues.Length)
    return otherValues[index];

  return null;
}
于 2012-05-10T10:58:08.550 回答