在C#中获得汇编描述的简化方法?

时间:2012-04-18 05:52:40

标签: c# linq reflection .net-4.0 lambda

我正在阅读.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();
}

简单地获取程序集描述是很多代码,我想知道使用LINQ或lambda表达式在.NET 3.5+中执行此操作是否更简单?

10 个答案:

答案 0 :(得分:28)

真的没有。你可以这样做一点'更流利':

 var descriptionAttribute = assembly
         .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
         .OfType<AssemblyDescriptionAttribute>()
         .FirstOrDefault();

 if (descriptionAttribute != null) 
     Console.WriteLine(descriptionAttribute.Description);

[编辑将Assembly更改为ICustomAttributeProvider,参见Simon Svensson回答)

如果您需要这种代码,请在ICustomAttributeProvider上创建一个扩展方法:

 public static T GetAttribute<T>(this ICustomAttributeProvider assembly, bool inherit = false) 
 where T : Attribute 
 {
     return assembly
         .GetCustomAttributes(typeof(T), inherit)
         .OfType<T>()
         .FirstOrDefault();
}

自Yuriy解释以来,自.Net 4.5以来,框架中提供了一种扩展方法:

var descriptionAttribute = 
    assembly.GetCustomAttribute<AssemblyDescriptionAttribute>();

答案 1 :(得分:5)

var attribute = Assembly.GetExecutingAssembly()
                    .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
                    .Cast<AssemblyDescriptionAttribute>().FirstOrDefault();
if (attribute != null)
{
    Console.WriteLine(attribute.Description);
}

答案 2 :(得分:4)

我会使用ICustomAttributeProvider的扩展方法来提供强类型GetCustomAttributes,它返回强类型的枚举。唯一的linq用法是调用FirstOrDefaultOfType

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>();
}

答案 3 :(得分:3)

按照@ ab-kolan的回答,它可能更简单:

    var description = Assembly
            .GetExecutingAssembly()
            .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
            .OfType<AssemblyDescriptionAttribute>()
            .FirstOrDefault()?
            .Description ?? "";

答案 4 :(得分:1)

虽然这段代码已经相对简洁,但可以利用一点LINQ来清理它。

AssemblyDescriptionAttribute attribute = assembly
    .GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
    .OfType<AssemblyDescriptionAttribute>()
    .SingleOrDefault();

if(attribute != null)
{
    Console.WriteLine(attribute.Description);
}

答案 5 :(得分:1)

我会做这样的事情:

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();
    }
}

答案 6 :(得分:0)

在这里 - 它可以很容易地压缩到两行代码 - 如果它太大了,你可以将它转储到扩展方法中:

public static string GetAssemblyDescription(this Assembly assembly)
{
    return assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)
        .OfType<AssemblyDescriptionAttribute>().SingleOrDefault()?.Description;
}

然后你只需使用这样的扩展方法:

Console.WriteLine(typeof(Program).Assembly.GetAssemblyDescription());

答案 7 :(得分:0)

如果您只对当前的执行过程感兴趣(而不是原始帖子的装配),那么它就是一个简单的一个班轮..

Console.WriteLine(Process.GetCurrentProcess().MainModule.FileVersionInfo.Comments);

答案 8 :(得分:0)

在这种情况下,您不需要LINQ或lambda表达式。

从.NET 4.5开始,您可以享受extension method来反映属性:

var descriptionAttribute = assembly.GetCustomAttribute<AssemblyDescriptionAttribute>();

if (descriptionAttribute != null)
    Console.WriteLine(descriptionAttribute.Description);

答案 9 :(得分:-2)

如果要引用“装配体信息”中的“说明”: Project's Assembly Information Window

[右键单击项目->应用程序->程序集信息]

我建议使用AssemblyInfo类, 您可以看到一个示例here

使用后,我会使用反射手握 const Portfolio = () => { // Directory Images const imageBaseURL = 'http://localhost:5000/uploads/'; const [dataCards, setDataCard] = useState([]); const [isLoading, setIsLoading] = useState(false); useEffect((err) => { setIsLoading(true); axios .get('http://localhost:5000/api/v1/cards') .then((res) => { console.log(res); setIsLoading(false); setDataCard(res.data.data); }) .catch(err); }, []); if (isLoading) { return <Spinner />; } else { return ( <div> <h1 className='title_portfolio'>Ils nous ont fait confiance !</h1> <Card dataCards={dataCards} imageBaseURL={imageBaseURL} /> </div> ); }}; ,然后这样做:

Type type