Как использовать Path.Combine с более чем двумя аргументами?
Я удивлен, что не перегрузка, которая может принимать строковый массив. Во всяком случае, лучший способ избежать наложения вызовов на Path.Combine?
pathValue = Path.Combine(path1, Path.Combine(path2, Path.Combine(path3, path4)))
Это кажется неэффективным, так как он приводит к созданию 4 новых строк, чтобы получить 1.
Ответы
Ответ 1
Эффективная сторона вещей не проблема IMO - это сторона удобства использования. Лично я думаю, что должна быть перегрузка:
Combine(string first, string second, string third, params string[] others)
У вас должно быть как минимум три, чтобы он не столкнулся с существующей двухпараметрической версией, если вы просто пишете Path.Combine("foo", "bar")
, но это, безусловно, поможет сделать код более понятным. Почему бы не открыть запрос функции на Connect?
Конечно, вы можете реализовать это самостоятельно (а в другом классе количество параметров не имеет большого значения):
public static string CombinePaths(string first, params string[] others)
{
// Put error checking in here :)
string path = first;
foreach (string section in others)
{
path = Path.Combine(path, section);
}
return path;
}
Ответ 2
Если у вас уже есть массив или IEnumerable, вы можете сделать это в одной строке...
// I'm assuming that you've got an array or IEnumerable<T> from somewhere
var paths = new string[] { path1, path2, path3, path4, path5, path6 };
string result = paths.Aggregate(Path.Combine);
Если нет, то как насчет написания собственного метода расширения для строки...
public static class PathExtension
{
public static string CombinePathWith(this string path1, string path2)
{
return Path.Combine(path1, path2);
}
}
..., который позволит вам связать их так:
string result = path1.CombinePathWith(path2)
.CombinePathWith(path3)
.CombinePathWith(path4)
.CombinePathWith(path5)
.CombinePathWith(path6);
Ответ 3
Очень просто реализовать его самостоятельно:
public string Combine(params string[] paths)
{
char[] pathSeparators = new char[]
{ Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar };
if(paths == null) throw new ArgumentNullException("paths");
if(paths.Length == 1) return paths[0];
StringBuilder pathBuilder = new StringBuilder();
foreach(string path in paths)
{
if(Path.IsPathRooted(path))
pathBuilder = new StringBuilder(path);
else
{
char last = pathBuilder.Length > 0 ?
pathBuilder[pathBuilder.Length - 1] :
path[path.Length - 1];
if(Array.IndexOf(pathSeparators, last) == -1)
pathBuilder.Append(Path.DirectorySeparatorChar);
pathBuilder.Append(path);
} // else
} // foreach
return pathBuilder.ToString();
}
[Test()]
public void CombinePaths()
{
string result = Combine(@"C:\Program Files\", @"Microsoft.NET", @"ADOMD.NET\", "90", "msadomdx.dll");
Assert.AreEqual(@"C:\Program Files\Microsoft.NET\ADOMD.NET\90\msadomdx.dll", result);
}