문제

이 비 컴파일 코드를 예를 들어 다음과 같습니다.

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 키워드와 직접 관련된 솔루션에만 관심이 있습니다. 목록과 다른 유사한 것들이 어떻게 작동하는지 알고 있습니다.

엑스트라 폴더 배열을 "폭발"하여 내용물을 다른 매개 변수와 함께 AppendFolders로 전달할 수 있도록하는 방법이 있습니까?

도움이 되었습니까?

해결책

한 가지 옵션은 params 매개 변수 an 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"});

다른 팁

그냥 통과하십시오. 폴더 매개 변수는 먼저 배열입니다. "매개 변수"기능은 약간의 컴파일러 마법이지만 필요하지 않습니다.

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

나는 당신이 정말로 "확장"하고 싶어하는 것처럼 보이기 때문에 "Collapse"라는 용어로 퀴즈를받을 것입니다. 그리고 솔루션이 "매개 변수 키워드와 직접 관련이있는 솔루션"과 "해결 방법에 관심이 없다"는 의미가 확실하지 않습니다. 결국, 당신은 컴파일러가 배열로 마법으로 패키지 또는 직접 문자열 배열을 전달해야합니다. 즉, 내 솔루션 (인터페이스를 변경하지 않고)은 다음과 같은 것입니다.

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

그러나 우리가 그렇게 멀리 갈 것이라면 - 목록을 확장 할 수도 있습니다.u003CT> 우아하게 처리하려면 :

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

빠르고 더러운 솔루션은 목록을 작성하는 것입니다.u003Cstring> 항목에서 나서 (ToArray ()와 함께)를 전달하십시오.

백 슬래시를 테스트 할 필요가 없습니다. path.combine 핸들 더러운 것들이 다소 괜찮습니다.

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

그리고 나는 목록을 사용하는 방법에 대한 교훈으로, 앞으로 솔루션을 찾는 사람이라면 누구나 약간의 설명을한다는 것을 의미하지는 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top