Похоже, что в .NET "массив перечислений" не является сильно типизированным понятием. MyEnum[]
считается реализующим не только IEnumerable
, но и IEnumerable
. (Я тоже сначала не поверил. )
// Returns true:
typeof(IEnumerable<DayOfWeek>).IsAssignableFrom(typeof(AttributeTargets[]))
// Outputs "3":
var listOfLists = new List<object> {
new[] { AttributeTargets.All },
new[] { ConsoleColor.Blue },
new[] { PlatformID.Xbox, PlatformID.MacOSX }
};
Console.WriteLine(listOfLists.OfType<IEnumerable<DayOfWeek>>().Count());
Итак, когда я просматриваю список на предмет всего, что реализует IEnumerable
, я получаю T[]
s и List
s и сгенерированные итератором IEnumerable
s, но я также получаю SomethingElse[]
s, которые мне не нужны.
Какой самый простой способ выяснить, реализует ли данный Type
(как в IsAssignableFrom выше) или данный экземпляр (как в OfType
выше) действительно и действительно, скажем, IEnumerable
?
Я поставил мистеру Скиту зеленую галочку, но как только я занес его код в Visual Studio, ReSharper предложил более лаконичную версию. Используйте ту версию, которая вам больше нравится.
public static IEnumerable<IEnumerable<T>> OfSequenceType<T>
(this IEnumerable source) where T : struct
{
return from sequence in source.OfType<IEnumerable<T>>()
let type = sequence.GetType()
where !type.IsArray || type.GetElementType() == typeof (T)
select sequence;
}