2008-10-10 38 views
5

把這個非編譯代碼,例如:是否有可能爆炸一個數組,使其元素可以傳遞給帶有params關鍵字的方法?

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連同其他參數?

+0

爲了確保我明白了,您希望將extraFolders數組作爲AppendFolders(extraFolders [0],extraFolders [1],...等等)發送到AppendFolders方法中? 有趣的問題,我很好奇,如果這是可能的,但我不知道如何...... – BFree 2008-10-10 19:28:58

+0

這正是我想要的。 – 2008-10-10 19:31:31

+0

你的澄清只是增加了更多的困惑。這些額外的物品是否被通過了這個或者沒有的重要部分?如果沒有,我的答案的前半部分就是你想要的。如果是,這是一個非常特殊的情況,由我的答案的後半部分處理。 – 2008-10-10 19:52:36

回答

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"}); 
1

一個快速和骯髒的解決方案將建立一個列表<字符串>從項目,然後傳遞(與ToArray())。

請注意,您不需要測試反斜槓。 Path.Combine處理the dirty things rather fine

7

只要通過它。 folders參數首先是一個數組。 「params」功能有一點編譯器魔力,但它不是必需的。

AppendFolders(extraFolders); 

現在,它是這個particulat實例,您必須首先添加一些東西到該數組。

List<string> lstFolders = new List<string>(extraFolders); 
lstFolder.Insert(0, callingModule); 
lstFolder.Insert(0, version); 
lstFolder.Insert(0, basefolder); 
return AppendFolders(lstFolders.ToArray()); 
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()); 
} 

我的意思並不是說就如何使用列表,就像一個小澄清任何人誰可能會沿尋找一個教訓未來的解決方案。

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(); 
} 

但是,如果我們要走到這一步 - 可能也只是延長列表<牛逼>能夠完美地處理這個問題:

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(); 
    } 
} 
相關問題