NullableFlagsSource
struct NullableFlagsSource
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
namespace Namotion.Reflection
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal readonly struct NullableFlagsSource
{
[System.Runtime.CompilerServices.Nullable(0)]
private readonly struct CacheKey : IEquatable<CacheKey>
{
public Type Type { get; set; }
[System.Runtime.CompilerServices.Nullable(2)]
[field: System.Runtime.CompilerServices.Nullable(2)]
public Assembly Assembly {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
[System.Runtime.CompilerServices.NullableContext(2)]
set;
}
public CacheKey(Type Type, [System.Runtime.CompilerServices.Nullable(2)] Assembly Assembly)
{
Type = Type;
Assembly = Assembly;
}
[System.Runtime.CompilerServices.NullableContext(0)]
[CompilerGenerated]
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("CacheKey");
stringBuilder.Append(" { ");
if (PrintMembers(stringBuilder))
stringBuilder.Append(' ');
stringBuilder.Append('}');
return stringBuilder.ToString();
}
[System.Runtime.CompilerServices.NullableContext(0)]
[CompilerGenerated]
private bool PrintMembers(StringBuilder builder)
{
builder.Append("Type = ");
builder.Append(Type);
builder.Append(", Assembly = ");
builder.Append(Assembly);
return true;
}
public static bool operator !=(CacheKey left, CacheKey right)
{
return !(left == right);
}
public static bool operator ==(CacheKey left, CacheKey right)
{
return left.Equals(right);
}
[CompilerGenerated]
public override int GetHashCode()
{
return EqualityComparer<Type>.Default.GetHashCode(Type) * -1521134295 + EqualityComparer<Assembly>.Default.GetHashCode(Assembly);
}
[System.Runtime.CompilerServices.NullableContext(0)]
[CompilerGenerated]
public override bool Equals(object obj)
{
if (obj is CacheKey)
return Equals((CacheKey)obj);
return false;
}
[CompilerGenerated]
public bool Equals(CacheKey other)
{
if (EqualityComparer<Type>.Default.Equals(Type, other.Type))
return EqualityComparer<Assembly>.Default.Equals(Assembly, other.Assembly);
return false;
}
[CompilerGenerated]
public void Deconstruct(out Type Type, [System.Runtime.CompilerServices.Nullable(2)] out Assembly Assembly)
{
Type = this.Type;
Assembly = this.Assembly;
}
}
private static Dictionary<CacheKey, NullableFlagsSource> _nullableCache = new Dictionary<CacheKey, NullableFlagsSource>();
[System.Runtime.CompilerServices.Nullable(2)]
public readonly byte[] NullableFlags;
public static NullableFlagsSource Create(Type type, [System.Runtime.CompilerServices.Nullable(2)] Assembly assembly = null)
{
Dictionary<CacheKey, NullableFlagsSource> nullableCache = _nullableCache;
CacheKey cacheKey = new CacheKey(type, assembly);
if (!nullableCache.TryGetValue(cacheKey, out NullableFlagsSource value)) {
value = new NullableFlagsSource(type, assembly);
Interlocked.CompareExchange(ref _nullableCache, new Dictionary<CacheKey, NullableFlagsSource>(nullableCache) {
[cacheKey] = value
}, nullableCache);
}
return value;
}
public static NullableFlagsSource Create(MemberInfo member)
{
return new NullableFlagsSource(member);
}
private NullableFlagsSource(Type type, [System.Runtime.CompilerServices.Nullable(2)] Assembly assembly)
{
byte[] nullableFlags = GetNullableFlags(type);
if (nullableFlags == null && (object)assembly != null)
nullableFlags = GetNullableFlags(assembly);
NullableFlags = nullableFlags;
}
private NullableFlagsSource(MemberInfo memberInfo)
{
NullableFlags = GetNullableFlags(memberInfo);
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private static byte[] GetNullableFlags<[System.Runtime.CompilerServices.Nullable(0)] T>(T provider) where T : ICustomAttributeProvider
{
object[] customAttributes = provider.GetCustomAttributes(false);
foreach (object obj in customAttributes) {
Type type = obj.GetType();
if (type.Name == "NullableContextAttribute" && type.Namespace == "System.Runtime.CompilerServices")
return new byte[1] {
(byte)type.GetRuntimeField("Flag").GetValue(obj)
};
}
return null;
}
}
}