// Copyright (c) Ben A Adams. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Reflection; using System.Threading; namespace System.Diagnostics.Internal { /// /// A helper class that contains utilities methods for dealing with reflection. /// public static class ReflectionHelper { private static PropertyInfo? tranformerNamesLazyPropertyInfo; /// /// Returns true if the is a value tuple type. /// public static bool IsValueTuple(this Type type) { return type.Namespace == "System" && type.Name.Contains("ValueTuple`"); } /// /// Returns true if the given is of type TupleElementNameAttribute. /// /// /// To avoid compile-time depencency hell with System.ValueTuple, this method uses reflection and not checks statically that /// the given is TupleElementNameAttribute. /// public static bool IsTupleElementNameAttribue(this Attribute attribute) { var attributeType = attribute.GetType(); return attributeType.Namespace == "System.Runtime.CompilerServices" && attributeType.Name == "TupleElementNamesAttribute"; } /// /// Returns 'TransformNames' property value from a given . /// /// /// To avoid compile-time depencency hell with System.ValueTuple, this method uses reflection /// instead of casting the attribute to a specific type. /// public static IList? GetTransformerNames(this Attribute attribute) { Debug.Assert(attribute.IsTupleElementNameAttribue()); var propertyInfo = GetTransformNamesPropertyInfo(attribute.GetType()); return propertyInfo?.GetValue(attribute) as IList; } private static PropertyInfo? GetTransformNamesPropertyInfo(Type attributeType) { #pragma warning disable 8634 return LazyInitializer.EnsureInitialized(ref tranformerNamesLazyPropertyInfo, #pragma warning restore 8634 () => attributeType.GetProperty("TransformNames", BindingFlags.Instance | BindingFlags.Public)); } } }