Упрощенный способ получить описание сборки в С#?
Я читал книгу .NET 2.0 и наткнулся на этот образец кода, который получает описание сборки приложений:
static void Main(string[] args)
{
Assembly assembly = Assembly.GetExecutingAssembly();
object[] attributes =
assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length > 0)
{
AssemblyDescriptionAttribute descriptionAttribute =
(AssemblyDescriptionAttribute)attributes[0];
Console.WriteLine(descriptionAttribute.Description);
}
Console.ReadKey();
}
Это довольно много кода, чтобы просто получить описание сборки, и я хотел бы знать, есть ли более простой способ сделать это в .NET 3.5+ с использованием LINQ или лямбда-выражений?
Ответы
Ответ 1
Нет, правда. Вы можете сделать это немного "более бегло", как это:
var descriptionAttribute = assembly
.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
.OfType<AssemblyDescriptionAttribute>()
.FirstOrDefault();
if (descriptionAttribute != null)
Console.WriteLine(descriptionAttribute.Description);
[ПРАВКА изменяет сборку на ICustomAttributeProvider, ср. ответ Саймона Свенссона)
И если вам очень нужен такой код, создайте метод расширения на ICustomAttributeProvider:
public static T GetAttribute<T>(this ICustomAttributeProvider assembly, bool inherit = false)
where T : Attribute
{
return assembly
.GetCustomAttributes(typeof(T), inherit)
.OfType<T>()
.FirstOrDefault();
}
Начиная с .Net 4.5, как объяснил Юрий, в структуре доступен метод расширения:
var descriptionAttribute =
assembly.GetCustomAttribute<AssemblyDescriptionAttribute>();
Ответ 2
var attribute = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
.Cast<AssemblyDescriptionAttribute>().FirstOrDefault();
if (attribute != null)
{
Console.WriteLine(attribute.Description);
}
Ответ 3
Я бы использовал метод расширения для ICustomAttributeProvider, чтобы обеспечить строго типизированный GetCustomAttributes
, который возвращает строго типизированный перечислимый. Единственное использование linq было бы вызовом FirstOrDefault
и OfType
public static void Main() {
Assembly assembly = Assembly.GetExecutingAssembly();
var descriptionAttribute = assembly
.GetCustomAttributes<AssemblyDescriptionAttribute>(inherit: false)
.FirstOrDefault();
if (descriptionAttribute != null) {
Console.WriteLine(descriptionAttribute.Description);
}
Console.ReadKey();
}
public static IEnumerable<T> GetCustomAttributes<T>(this ICustomAttributeProvider provider, bool inherit) where T : Attribute {
return provider.GetCustomAttributes(typeof(T), inherit).OfType<T>();
}
Ответ 4
После ответа @ab-kolan это может быть проще:
var description = Assembly
.GetExecutingAssembly()
.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
.OfType<AssemblyDescriptionAttribute>()
.FirstOrDefault()?
.Description ?? "";
Ответ 5
Хотя этот код уже относительно краток, вы можете использовать немного LINQ, чтобы очистить его прикосновением.
AssemblyDescriptionAttribute attribute = assembly
.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
.OfType<AssemblyDescriptionAttribute>()
.SingleOrDefault();
if(attribute != null)
{
Console.WriteLine(attribute.Description);
}
Ответ 6
Я бы сделал что-то вроде этого:
public static class AssemblyExtensions
{
public static string GetDescription(this Assembly assembly)
{
var attribute = assembly.GetCustomAttributes(typeof (AssemblyDescriptionAttribute), false)
.Select(a => a as AssemblyDescriptionAttribute).FirstOrDefault();
if (attribute == null)
{
return String.Empty;
}
return attribute.Description;
}
}
class Program
{
static void Main(string[] args)
{
var assembly = Assembly.GetExecutingAssembly();
Console.WriteLine(assembly.GetDescription());
Console.ReadKey();
}
}
Ответ 7
Здесь вы идете - он легко конденсируется до двух строк кода - и если это слишком большое, вы можете сбросить его в метод расширения:
public static string GetAssemblyDescription(this Assembly assembly)
{
return assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
.OfType<AssemblyDescriptionAttribute>().SingleOrDefault()?.Description;
}
Затем вы просто используете метод расширения следующим образом:
Console.WriteLine(typeof(Program).Assembly.GetAssemblyDescription());
Ответ 8
Если вас интересует только текущий процесс выполнения (против сборки в соответствии с исходным сообщением), тогда это простой один вкладыш.
Console.WriteLine(Process.GetCurrentProcess().MainModule.FileVersionInfo.Comments);
Ответ 9
Вам не нужны LINQ или лямбда-выражения в этом случае.
Начиная с .NET 4.5 вы можете использовать метод расширения для отражения атрибута:
var descriptionAttribute = assembly.GetCustomAttribute<AssemblyDescriptionAttribute>();
if (descriptionAttribute != null)
Console.WriteLine(descriptionAttribute.Description);