gpt4 book ai didi

c# - 使用反射确定 C# 中引用类型的可空性

转载 作者:行者123 更新时间:2023-12-04 01:27:27 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





How to use .NET reflection to check for nullable reference type

(4 个回答)


去年关闭。




我有使用 C#-8 和可空类型的 .NET Core 项目。

我有以下类(class)

public class MyClass
{
public int? NullableInt { get; private set; }

public string? NullableString { get; private set; }

public string NonNullableString { get; private set; }

public MySubClass? MyNullableSubClass { get; private set; }

}

我需要能够遍历所有属性是类并确定哪些属性可以为空。

所以我的代码看起来像这样

public IEnumerable<string> GetNullableProperties(Type type)
{
var nullableProperties = new List<string>();
foreach (var property in type.GetProperties())
{
var isNullable = false;
if (property.PropertyType.IsValueType)
{
isNullable = Nullable.GetUnderlyingType(property.PropertyType) != null;
} else {
var nullableAttribute = property.PropertyType.CustomAttributes
.FirstOrDefault(a => a.AttributeType.Name == "NullableAttribute");
isNullable = nullableAttribute != null;
}

if (isNullable)
{
nullableProperties.Add(property.propertyType.Name)
}
}
return nullableProperties;
}

传递 MyClass的类型此方法返回 ["NullableInt", "NullableString", "NonNullableString", "MyNullableSubClass"] .

但是,预期的返回值是 ["NullableInt", "NullableString", "MyNullableSubClass"] .
NonNullableString的原因属性被确定为可为空的,因为它具有 Nullable 属性。

我的理解是在判断一个引用类型是否可以为空时,需要检查它是否有Nullable属性。但是,对于字符串类型,情况似乎并非如此。似乎所有字符串都定义了可空属性。有没有办法找出 string可以为空(即使用可空运算符 ? 定义)。

最佳答案

我想出了完整的解决方案。我们需要检查属性和类上的自定义属性。


...


private const byte NonNullableContextValue = 1;
private const byte NullableContextValue = 2;

public IEnumerable<string> GetNullableProperties(Type type)
{
foreach (var property in type.GetProperties())
{
var isNullable = property.PropertyType.IsValueType
? Nullable.GetUnderlyingType(property.PropertyType) != null;
: IsReferenceTypePropertyNullable(property);

if (isNullable)
{
nullableProperties.Add(property.propertyType.Name)
}
}
return nullableProperties;
}

private function bool IsReferenceTypePropertyNullable(PropertyInfo property)
{
var classNullableContextAttribute = property.DeclaringType.CustomerProperties
.FirstOrDefault(c => c.AttributeType.Name == "NullableContextAttribute")

var classNullableContext = classNullableContextAttribute
?.ConstructorArguments
.First(ca => ca.ArgumentType.Name == "Byte")
.Value;

// EDIT: This logic is not correct for nullable generic types
var propertyNullableContext = property.CustomAttributes
.FirstOrDefault(c => c.AttributeType.Name == "NullableAttribute")
?.ConstructorArguments
.First(ca => ca.ArgumentType.Name == "Byte")
.Value;

// If the property does not have the nullable attribute then it's
// nullability is determined by the declaring class
propertyNullableContext ??= classNullableContext;

// If NullableContextAttribute on class is not set and the property
// does not have the NullableAttribute, then the proeprty is non nullable
if (propertyNullableContext == null)
{
return true;
}

// nullableContext == 0 means context is null oblivious (Ex. Pre C#8)
// nullableContext == 1 means not nullable
// nullableContext == 2 means nullable
switch (propertyNullableContext)
{
case NonNullableContextValue:
return false;
case NullableContextValue:
return true;
default:
throw new Exception("My error message");
}
}

以下是有关可为空的上下文值的一些信息: https://www.postsharp.net/blog/post/PostSharp-internals-handling-csharp-8-nullable-reference-types

关于c# - 使用反射确定 C# 中引用类型的可空性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61626220/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com