Tampaknya ini berfungsi, setidaknya pada tipe yang saya uji.
Anda harus melewati PropertyInfo
untuk properti yang Anda minati, dan juga Type
properti yang ditentukan ( bukan tipe turunan atau induk - harus tipe yang tepat):
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;
}
Lihat dokumen ini untuk detailnya.
Inti umum adalah bahwa properti itu sendiri dapat memiliki [Nullable]
atribut di atasnya, atau jika tidak tipe terlampir mungkin memiliki [NullableContext]
atribut. Pertama-tama kita mencari [Nullable]
, maka jika kita tidak menemukannya kita mencari [NullableContext]
pada tipe penutup.
Kompiler mungkin menanamkan atribut ke dalam rakitan, dan karena kita mungkin melihat jenis dari rakitan yang berbeda, kita perlu melakukan beban hanya refleksi.
[Nullable]
mungkin dipakai dengan array, jika properti itu generik. Dalam hal ini, elemen pertama mewakili properti aktual (dan elemen lebih lanjut mewakili argumen generik). [NullableContext]
selalu dipakai dengan satu byte.
Nilai 2
sarana "nullable". 1
berarti "tidak dapat dibatalkan", dan 0
berarti "tidak menyadari".
[NullableContext(2), Nullable((byte) 0)]
ke jenis (Foo
) - sehingga ini apa untuk memeriksa, tapi aku perlu menggali lebih memahami aturan bagaimana menafsirkan itu!