代码之家  ›  专栏  ›  技术社区  ›  Rick Minerich

是否可以分解数组以便将其元素传递给带有params关键字的方法?

  •  5
  • Rick Minerich  · 技术社区  · 16 年前

    以这个非编译代码为例:

    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?

    5 回复  |  直到 16 年前
        1
  •  1
  •   Mark Cidade    16 年前

    一种选择是 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"});
    
        2
  •  7
  •   James Curran    16 年前

    只要通过它。folders参数首先是一个数组。“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());
    
        3
  •  2
  •   Mark Brackett    16 年前

    我会用“崩溃”这个词来反驳,因为你似乎真的想“扩张”。我不知道你所说的解决方案“直接与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();
        }
    }
    
        4
  •  1
  •   Community CDub    8 年前

    一个快速而肮脏的解决方案是从项目中构建一个列表<string>,然后传递它(使用toarray())。

    注意,您不需要测试反斜杠。路径。合并句柄 the dirty things rather fine .

        5
  •  1
  •   MojoFilter    16 年前

    我认为俄勒冈主持人的答案可能就是你想走的路。为了详细说明这一点,他建议这样做:

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

    我的意思并不是说,作为一个关于如何使用列表的课程,对任何将来可能会一起寻找解决方案的人来说,这只是一个小小的澄清。