| File: Utilities\TypeUtilities.cs | Web Access |
| Project: src\msbuild\src\Framework\Microsoft.Build.Framework.csproj (Microsoft.Build.Framework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Linq; using System.Reflection; namespace Microsoft.Build.Shared { /// <summary> /// Utility extension methods for working with <see cref="Type"/> metadata in a resilient manner. /// </summary> /// <remarks> /// These helpers intentionally: /// - Catch and suppress non-critical reflection/type loading exceptions so callers can probe for attributes safely /// even when some referenced types cannot be loaded in the current load context. /// - Compare attribute types by their simple <see cref="MemberInfo.Name"/> (e.g. <c>ObsoleteAttribute</c>) rather than /// full name or assembly-qualified name. This mirrors existing MSBuild behavior but means ambiguous attribute /// short names across different assemblies cannot be distinguished here. /// </remarks> internal static class TypeUtilities { /// <summary> /// Determines whether the specified <paramref name="type"/> is decorated with an attribute of type <typeparamref name="T"/>. /// </summary> public static bool HasAttribute<T>(this Type type) where T : Attribute => type.HasAttribute(typeof(T).Name); /// <summary> /// Determines whether the specified <paramref name="type"/> is decorated with an attribute whose simple type name /// equals <paramref name="attributeName"/>. /// </summary> public static bool HasAttribute(this Type type, string attributeName) { if (type == null) { return false; } return CustomAttributeData .GetCustomAttributes(type) .Any(attr => SafeGetAttributeName(attr) == attributeName); } /// <summary> /// Safely retrieves the simple name of an attribute's type, swallowing non-critical reflection exceptions. /// </summary> /// <param name="attr">The attribute metadata.</param> /// <returns>The simple attribute type name, or <c>null</c> if it cannot be resolved.</returns> private static string? SafeGetAttributeName(CustomAttributeData attr) => attr.AttributeType?.Name; } }