5

たとえば、次の非コンパイル コードを見てください。

public string GetPath(string basefolder, string[] extraFolders)
{
    string version = Versioner.GetBuildAndDotNetVersions();
    string callingModule = StackCrawler.GetCallingModuleName();
    return AppendFolders(basefolder, version, callingModule, extraFolders);
}
private string AppendFolders(params string[] folders)
{
    string outstring = folders[0];
    for (int i = 1; i < folders.Length; i++)
    {
        string fixedPath = folders[i][0] == '\\' ? folders[i].Substring(1) : folders[i];
        Path.Combine(outstring, fixedPath);
    }
    return outstring;
}

この例は、私が使用しているテスト コードのやや簡略化されたバージョンです。param キーワードに直接関係するソリューションにのみ関心があります。リストやその他の同様のものがどのように機能するかを知っています。

extraFolders 配列を「展開」して、その内容を他のパラメータとともに AppendFolders に渡す方法はありますか?

4

5 に答える 5

7

渡すだけです。フォルダー パラメーターは、最初は配列です。「params」機能はちょっとしたコンパイラの魔法ですが、必須ではありません。

AppendFolders(extraFolders);

さて、この特定のインスタンスでは、最初にその配列にいくつかのものを追加する必要があります。

List<string> lstFolders = new List<string>(extraFolders);
lstFolder.Insert(0, callingModule);
lstFolder.Insert(0, version);
lstFolder.Insert(0, basefolder);
return AppendFolders(lstFolders.ToArray());
于 2008-10-10T19:33:00.410 に答える
2

あなたが本当に「拡大」したいと思うので、私は「崩壊」という用語をいじくりまわします。そして、「paramsキーワードと直接関係がある」ソリューションと「回避策に興味がない」というソリューションが何を意味するのかわかりません。最終的には、コンパイラが魔法のように配列にパッケージ化するいくつかの文字列を渡すか、文字列の配列を直接渡す必要があります。そうは言っても、私の解決策(インターフェースを変更しない)は次のようになります。

return AppendFolders(new string[] { basefolder, version, callingModule }.Concat(extraFolders).ToArray());

編集:

拡張メソッドを介して演算子を追加することはできませんが、次のことができます。

return AppendFolders(new string[] { baseFolder, callingModuleName, version }.Concat(extraFolders));

public static T[] Concat<T>(this T[] a, T[] b) {
   return ((IEnumerable<T>)a).Concat(b).ToArray();
}

しかし、ここまで進んでいくとしたら、List <T>を拡張して、これをエレガントに処理することもできます。

return AppendFolders(new Params<string>() { baseFolder, callingModuleName, version, extraFolders });

class Params<T> : List<T> {
    public void Add(IEnumerable<T> collection) {
       base.AddRange(collection);
    }

    public static implicit operator T[](Params<T> a) {
       return a.ToArray();
    }
}
于 2008-10-10T19:51:57.330 に答える
1

OregonGhostの答えはおそらくあなたが行きたい方法だと思います。それについて詳しく説明するために、彼は次のようなことを提案しています。

public string GetPath(string basefolder, string[] extraFolders)
{
    string version = Versioner.GetBuildAndDotNetVersions();
    string callingModule = StackCrawler.GetCallingModuleName();

    List<string> parameters = new List<string>(extraFolders.Length + 3);
    parameters.Add(basefolder);
    parameters.Add(version);
    parameters.Add(callingModule);
    parameters.AddRange(extraFolders);
    return AppendFolders(parameters.ToArray());
}

そして、私はそれをリストの使い方のレッスンとして、将来解決策を探しに来るかもしれない人のためのちょっとした説明としてという意味ではありません。

于 2008-10-10T19:45:20.043 に答える
1

1つのオプションは、paramsパラメーターをobject[]:にすることです。

static string appendFolders(params object[] folders)
 { return (string) folders.Aggregate("",(output, f) => 
                       Path.Combine( (string)output
                                    ,(f is string[]) 
                                      ? appendFolders((object[])f)
                                      : ((string)f).TrimStart('\\')));
 }

より強く型付けされたものが必要な場合、別のオプションは、暗黙の変換演算子を使用してカスタムの共用体型を作成することです。

  static string appendFolders(params StringOrArray[] folders)
     { return folders.SelectMany(x=>x.AsEnumerable())
                     .Aggregate("",
                       (output, f)=>Path.Combine(output,f.TrimStart('\\')));
     }

   class StringOrArray
     { string[] array;

       public IEnumerable<string> AsEnumerable()
        { return soa.array;}

       public static implicit operator StringOrArray(string   s)   
        { return new StringOrArray{array=new[]{s}};}

       public static implicit operator StringOrArray(string[] s)  
        { return new StringOrArray{array=s};}
     }

いずれの場合も、これコンパイルされます:

appendFolders("base", "v1", "module", new[]{"debug","bin"});
于 2008-10-10T21:14:32.263 に答える
1

手っ取り早い解決策は、項目から List<string> を作成し、それを (ToArray() を使用して) 渡すことです。

バックスラッシュをテストする必要がないことに注意してください。Path.Combine は、汚れたものをかなりうまく処理します。

于 2008-10-10T19:23:25.687 に答える