С выходом C# 3.0 увеличилось количество способов перебрать элементы коллекции. Но всё же самым выразительным способом перебора элементов остался цикл.
Например, реализуем перебор всех свойств объекта и распечатаем те из них, у которых есть аттрибут DisplayNameAttribute.
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace Home.Andir.Examples
{
class Foo
{
[Category("Основные свойства")]
[DisplayName("Свойство 1")]
public string Property1 { get; set; }
[Category("Основные свойства")]
[DisplayName("Свойство 2")]
public string Property2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
Action<PropertyInfo, DisplayNameAttribute> PrintToConsole =
(p, attr) => Console.WriteLine("\t{0} : {1}", p.Name, attr.DisplayName);
Console.WriteLine("Foo properties (with foreach):");
foreach (var p in typeof(Foo).GetProperties())
{
foreach (var attr in p.GetCustomAttributes(false))
if (attr is DisplayNameAttribute)
PrintToConsole(p, attr as DisplayNameAttribute);
}
Console.WriteLine("Foo properties (with foreach+linq 1):");
foreach (var p in typeof(Foo).GetProperties())
{
var attributes = from attr in p.GetCustomAttributes(false)
where attr is DisplayNameAttribute
select attr as DisplayNameAttribute;
attributes
.ToList()
.ForEach(attr => PrintToConsole(p, attr));
}
Console.WriteLine("Foo properties (with linq 1):");
typeof(Foo).GetProperties()
.ToList()
.ForEach(p =>
{
var attributes = from attr in p.GetCustomAttributes(false)
where attr is DisplayNameAttribute
select attr as DisplayNameAttribute;
attributes
.ToList()
.ForEach(attr => PrintToConsole(p, attr));
});
Console.WriteLine("Foo properties (with linq 2):");
typeof(Foo).GetProperties()
.ToList()
.ForEach(p =>
{
p.GetCustomAttributes(false)
.Where(attr => attr is DisplayNameAttribute)
.Cast<DisplayNameAttribute>()
.ToList()
.ForEach(attr => PrintToConsole(p, attr));
});
Console.ReadKey();
}
}
}
На первом месте по читаемости поставлю первый вариант с циклом. На втором месте последний четвёртый конвеерный способ перебора и фильтрации, но читаемость его гораздо хуже и, в первую очередь, из-за невозможности с первого взгляда объяснить сущность происходящего в коде. Остальные варианты в силу их гибридности смотрятся ещё хуже.
Не злоупотребляйте функциональным стилем в пользу читаемости! :-)
Открыл для себя ваш блог, подписываюсь :)
ОтветитьУдалить