(Примечание: см. Редактирование ...)
Если вы заранее не знаете, есть ли у вас строковый массив или массив массивов строк, вам нужно условно вызвать SelectMany
:
string[][] multi = words as string[][];
string[] flattened = multi == null ? words : multi.SelectMany(x => x).ToArray();
Обратите внимание, что в этом случае, если вы измените содержимое flattened
, это изменит либо words
(если оно уже было плоским), либо просто изменит копию (если это был зубчатый массив) ). Если вы хотите сделать это согласованным, вы можете вызвать words.ToArray()
во втором операнде условного оператора:
string[] flattened =
multi == null ? words.ToArray() : multi.SelectMany(x => x).ToArray();
Нет ли способа избежать двусмысленности, с которой можно начать? В частности, если вы контролируете соответствующие запросы LINQ to XML, вы должны быть в состоянии заставить их давать согласованный тип результата.
РЕДАКТИРОВАТЬ: Я только что понял, что если вы не знаете тип данных для начала, то words
предположительно объявляется как просто object
или, возможно, IEnumerable
. В этом случае вы бы хотели что-то вроде этого:
public string[] Flatten(object words)
{
string[][] multi = words as string[][];
if (multi != null)
{
return multi.SelectMany(x => x).ToArray();
}
string[] single = words as string[];
if (single != null)
{
return single.ToArray(); // Defensive copy; remove if not needed
}
throw new ArgumentException("Argument must be string[] or string[][]");
}
Это все еще очень странно - вам непременно следует попытаться сделать так, чтобы запросы давали вместо вас согласованный тип результата.