Чтобы расширить на решение Джо , входные данные не должны быть массивом. Это может быть IEnumerable<T>
, что позволяет передавать любой источник данных. И как только вы это сделаете, он начинает выглядеть так, как будто это должен быть метод расширения. Кроме того, вместо того, чтобы всегда предполагать, что в коллекции будет столько элементов, сколько и входных параметров, иногда удобно допускать несовпадения чисел.
public static void AssignTo<T>(this IEnumerable<T> source, out T dest1, out T dest2)
{
using (var e = source.GetEnumerator())
{
dest1 = e.MoveNext() ? e.Current : default(T);
dest2 = e.MoveNext() ? e.Current : default(T);
}
}
Тогда этот код:
string x, y;
"x".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);
"x,y".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);
"x,y,z".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);
выведет:
x,
x, y
x, y
Почему вы хотите разрешить передачу неверного списка размеров? Допустим, вы анализируете строки запроса. В Python вы хотели бы сказать key, value = query.split('=')
, но это не сработает, потому что key
является допустимым запросом, и вы также можете получить key=value=value
, оба из которых могут вызвать исключение. Обычно вам нужно написать
string[] kv = query.Split('=');
string key = kv[0];
string value = kv.Length > 1 ? kv[1] : null;
но вместо этого вы можете просто написать
string key, value;
query.Split('=').AssignTo(out key, out value);
Если вам требуется точное количество аргументов, просто бросьте исключение вместо присвоения нуля:
public static void AssignToExact<T>(this IEnumerable<T> source, out T dest1, out T dest2)
{
using (var e = source.GetEnumerator())
{
if (e.MoveNext()) dest1 = e.Current;
else throw new ArgumentException("Only 0 of 2 arguments given", "source");
if (e.MoveNext()) dest2 = e.Current;
else throw new ArgumentException("Only 1 of 2 arguments given", "source");
if (e.MoveNext()) throw new ArgumentException("More than 2 arguments given", "source");
}
}