Есть следующий класс
public class Request
{
public int Downtime {get;set;}
}
свойство Downtime
содержит кол-во минут. Подскажите как реализовать свой атрибут по аналогии с DisplayFormat
, т.е. что бы для свойства можно было указать какие то свойства, а внутри будет скрыта некоторая логика, например: $"{downtime/60}:{downtime%60}"
).
Мне это необходимо для создания универсального метода выгрузки результата запроса в excel. Заготовка метода выглядит так:
public void PrintRows<T>(ExcelWorksheet sheet, IEnumerable<T> rows, bool printTitle = false) where T: class
{
var columns = (from property in typeof(T).GetProperties()
let attribute = property.GetCustomAttributes(typeof(DisplayAttribute), true).SingleOrDefault() as DisplayAttribute
let format = property.GetCustomAttributes(typeof(DisplayFormatAttribute), true).SingleOrDefault() as DisplayFormatAttribute
where attribute != null
orderby attribute.Order
select new
{
Property = property,
Order = attribute.Order,
Name = attribute.Name,
Format = format?.DataFormatString ?? string.Empty
});
var rowNumber = 1;
if (printTitle)
{
foreach (var column in columns)
{
sheet.Cells[rowNumber, column.Order].Value = column.Name;
}
rowNumber++;
}
foreach (var row in rows)
{
foreach (var column in columns)
{
var value = column.Property.GetValue(row, null);
sheet.Cells[rowNumber, column.Order].Value = value;
if (!string.IsNullOrEmpty(column.Format))
{
sheet.Cells[rowNumber, column.Order].Style.Numberformat.Format = column.Format;
}
}
rowNumber++;
}
}
Возможно такой пример подойдет вам или натолкнет на мысль в нужном направлении.
Заведем базовый атрибут для кастомного форматирования:
[AttributeUsage(AttributeTargets.Property)] // Можно применять только к свойствам
public abstract class CustomFormatAttribute : Attribute
{
public abstract string Format(object value);
}
Пара реализаций для примера:
public class TimeFormatAttribute : CustomFormatAttribute
{
public override string Format(object value)
{
var time = (int)value;
return $"{time / 60 :00}:{time % 60 :00}";
}
}
public class MoneyFormatAttribute : CustomFormatAttribute
{
public override string Format(object value)
{
var money = (decimal)value;
return $"{value} руб.";
}
}
Класс элемента:
class Item
{
public int Number { get; set; }
[TimeFormat]
public int Time { get; set; }
[MoneyFormat]
public decimal Money { get; set; }
}
Пусть теперь у нас имеется некая коллекция таких элементов:
var items = new[]
{
new Item { Number = 10, Time = 300, Money = 299.95M },
new Item { Number = 20, Time = 250, Money = 287.95M },
new Item { Number = 30, Time = 200, Money = 275.95M },
new Item { Number = 40, Time = 150, Money = 263.95M },
new Item { Number = 50, Time = 100, Money = 251.95M }
};
Применяем кастомное форматирование:
var props = typeof(Item).GetProperties();
foreach (var item in items)
{
foreach (var prop in props)
{
var value = prop.GetValue(item);
var attribute = prop.GetCustomAttribute<CustomFormatAttribute>();
Console.WriteLine(attribute?.Format(value) ?? value);
}
Console.WriteLine();
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Пишу например название класса, мне Intellisense подсказывает правильный класс, но он не выделяется в подсказке, а соотвественно я не могу просто...
Как можно в записи вывести родительские рубрики?
Как обработать код так, чтобы после проверки radiobutton не пересылало на другой сайт, а всё оставалось на том же, ну то есть когда ты обрабатываешь...