[c#] .NET 리플렉션을 사용하여 nullable 참조 유형을 확인하는 방법
C # 8.0에는 nullable 참조 형식이 도입되었습니다. nullable 속성을 가진 간단한 클래스는 다음과 같습니다.
public class Foo
{
public String? Bar { get; set; }
}
리플렉션을 통해 클래스 속성에서 nullable 참조 유형을 사용하는지 확인하는 방법이 있습니까?
답변
이것은 적어도 테스트 한 유형에서 작동하는 것으로 보입니다.
당신은을 전달해야 PropertyInfo
또한에 관심이있는 속성과 Type
그 속성에 정의 된 ( 하지 파생 또는 부모 유형 – 그것은 정확한 유형이어야한다) :
public static bool IsNullable(Type enclosingType, PropertyInfo property)
{
if (!enclosingType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Contains(property))
throw new ArgumentException("enclosingType must be the type which defines property");
var nullable = property.CustomAttributes
.FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute");
if (nullable != null && nullable.ConstructorArguments.Count == 1)
{
var attributeArgument = nullable.ConstructorArguments[0];
if (attributeArgument.ArgumentType == typeof(byte[]))
{
var args = (ReadOnlyCollection<CustomAttributeTypedArgument>)attributeArgument.Value;
if (args.Count > 0 && args[0].ArgumentType == typeof(byte))
{
return (byte)args[0].Value == 2;
}
}
else if (attributeArgument.ArgumentType == typeof(byte))
{
return (byte)attributeArgument.Value == 2;
}
}
var context = enclosingType.CustomAttributes
.FirstOrDefault(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.NullableContextAttribute");
if (context != null &&
context.ConstructorArguments.Count == 1 &&
context.ConstructorArguments[0].ArgumentType == typeof(byte))
{
return (byte)context.ConstructorArguments[0].Value == 2;
}
// Couldn't find a suitable attribute
return false;
}
자세한 내용은 이 문서 를 참조하십시오.
일반적으로 요점은 속성 자체에 [Nullable]
특성이 있거나 둘러싸는 유형이없는 경우 [NullableContext]
특성 이있을 수 있다는 것입니다. 먼저를 [Nullable]
찾은 다음 찾지 못하면 [NullableContext]
둘러싸는 유형을 찾습니다 .
컴파일러는 속성을 어셈블리에 임베드 할 수 있으며 다른 어셈블리에서 유형을 볼 수 있으므로 리플렉션 전용로드를 수행해야합니다.
[Nullable]
속성이 제네릭 인 경우 배열로 인스턴스화 될 수 있습니다. 이 경우 첫 번째 요소는 실제 속성을 나타내고 추가 요소는 일반 인수를 나타냅니다. [NullableContext]
항상 단일 바이트로 인스턴스화됩니다.
값은 2
“널링 가능” 을 의미합니다. 1
“널링 가능하지 않음”을 0
의미하고 “명백하지 않음”을 의미합니다.