Подтвердить что ты не робот

Упрощенный способ получить описание сборки в С#?

Я читал книгу .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 или лямбда-выражений?

4b9b3361

Ответ 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);