6

私はそのようなことをしたいと思います:

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

そのため、params の配列を再度渡したいのです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

ConcatおよびToArray拡張メソッドを使用できます。

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

前処理メッセージ

すべてのGetMessage(...)呼び出しで新しい配列を作成したくない場合は、最初にFirstValue一度に1回Messageに挿入できます。そして、GetMessage(...)はstring.Format(...)のotherValuesパラメーターを使用します。

Messageプロパティは、FirstValueが設定された後、たとえばコンストラクターまたは次のようなinitメソッドで一度初期化さます。

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

InitMessageメソッドは、 Messageの最初のインデックスをFirstValueで初期化、残りのインデックスを "{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"

InitMessageはメッセージを次のように変更します
"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 に答える
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 に答える
0

離散要素を渡す

すべての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 に答える
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 に答える