สิ่งนี้ดูเหมือนจะใช้งานได้อย่างน้อยในประเภทที่ฉันทดสอบด้วย
คุณต้องผ่าน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
หมายถึง "nullable" 1
หมายถึง "ไม่เป็นโมฆะ" และ0
หมายถึง "ลบเลือน"
[NullableContext(2), Nullable((byte) 0)]
ไปที่ประเภท (Foo
) - เพื่อให้เป็นสิ่งเพื่อตรวจสอบ แต่ฉันต้องขุดเพิ่มเติมเพื่อทำความเข้าใจกฎของวิธีการตีความว่า!