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

C# 是否可以分解数组,以便将其元素传递给具有params关键字的方法?,c#,parameters,keyword,variadic-functions,params-keyword,C#,Parameters,Keyword,Variadic Functions,Params Keyword,以这段非编译代码为例: public string GetPath(string basefolder, string[] extraFolders) { string version = Versioner.GetBuildAndDotNetVersions(); string callingModule = StackCrawler.GetCallingModuleName(); return AppendFolders(basefolder, version, ca

以这段非编译代码为例:

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;
}
publicstringgetpath(stringbasefolder、string[]extraFolders)
{
string version=Versioner.GetBuildAndDotNetVersions();
string callingModule=StackCrawler.GetCallingModuleName();
返回附加文件夹(基本文件夹、版本、调用模块、外部文件夹);
}
私有字符串文件夹(参数字符串[]文件夹)
{
字符串超出=文件夹[0];
对于(inti=1;i
这个例子是我正在使用的测试代码的简化版本。请注意,我只对与param关键字直接相关的解决方案感兴趣。我知道列表和其他类似的东西是如何工作的


是否有一种方法可以“分解”extraFolders数组,以便将其内容与其他参数一起传递到AppendFolders中?

一个快速而肮脏的解决方案是从项目中构建一个列表,然后传递该列表(使用ToArray()


注意,您不需要测试反斜杠。路径。组合手柄。

只需传递它。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());
List lstFolders=新列表(外部文件夹);
lstFolder.Insert(0,调用模块);
lstFolder.Insert(0,版本);
lstFolder.Insert(0,basefolder);
返回AppendFolders(lstFolders.ToArray());

我认为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());
}
publicstringgetpath(stringbasefolder、string[]extraFolders)
{
string version=Versioner.GetBuildAndDotNetVersions();
string callingModule=StackCrawler.GetCallingModuleName();
列表参数=新列表(extraFolders.Length+3);
添加参数(basefolder);
参数。添加(版本);
添加(调用模块);
参数.AddRange(外部文件夹);
返回AppendFolders(parameters.ToArray());
}

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

我会用“崩溃”这个词来狡辩,因为你似乎真的想“扩展”。我不知道你所说的解决方案“与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();
}
returnappendfolders(新字符串[]{baseFolder,callingModuleName,version}.Concat(extraFolders));
公共静态T[]Concat(此T[]a,T[]b){
return((IEnumerable)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();
    }
}
返回AppendFolders(新参数(){baseFolder,callingModuleName,version,extraFolders});
类参数:列表{
公共void添加(IEnumerable集合){
base.AddRange(集合);
}
公共静态隐式运算符T[](参数a){
返回a.ToArray();
}
}

一个选项是将
参数设置为
对象[]

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

在某些情况下,它无法正确处理反斜杠。在过去,我以双反斜杠结束。ex.Blah\\Blah当这可能是一个你可以存档的bug时-如果你想继续做反斜杠的事情,至少使用Path.directoryseportorchar而不是硬编码的反斜杠。Path.Combine在第二条路径以反斜杠开始时会有问题。为了确保我理解,是否希望将extraFolders数组作为AppendFolders(extraFolders[0]、extraFolders[1]、…等)发送到AppendFolders方法中?有趣的问题,我很好奇这是否可能,尽管我不知道如何…你的澄清只是增加了更多的困惑。传递的额外项目是否是其中的重要部分?如果不是,我的前半部分答案就是你想要的。如果是,这是一个非常特殊的情况,由我的回答的后半部分处理。两者都很重要,但它们所使用的上下文并不重要。我想说的是,我不在乎它们是路径还是我在使用路径。Combine,我只想要一个简单的一行程序,将两组参数组合在一起,这样它们就可以传递到params方法中。我想重点是,你不能只向数组中添加内容:)这与我想要的非常接近。优雅且类似于编译器的功能。同样酷的是:新字符串[]{baseFolder,callingModuleName,version}+extraFolders
appendFolders("base", "v1", "module", new[]{"debug","bin"});