首页 > 解决方案 > 使用类型动态返回 null 的枚举

问题描述

在序列化程序中,我有

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var enumText = reader.Value.ToString();
        var enumType = Nullable.GetUnderlyingType(objectType) ?? objectType;
        var defaultValue = GetDefault(objectType);
        //TODO: If empty or invalid, return null
        if (enumText == string.Empty)
        {
            return defaultValue;
        }

        ...
    }

objectType 是System.Nullable``1[[SomeEnum]]SomeEnum 是普通枚举的地方

GetDefault返回System.Nullable[SomeEnum]value的实例应该是什么null

我试过 Activator.CreateInstance(objectType);which 返回null而不是(SomeEnum?)null

我也试过

    public object GetDefault(Type t)
    {
        return GetType().GetMethod("GetDefaultGeneric").MakeGenericMethod(t).Invoke(this, null);
    }

    public T GetDefaultGeneric<T>()
    {
        return default(T);
    }

这也返回 null

是否可以(SomeEnum?)null从 Type 对象返回?

我用这样的单元测试来测试它:

        var converter = new CustomStringEnumConverter();

        var result = converter.ReadJson(_readerMock.Object, nullableEnumType, "bad value", new JsonSerializer());
        result.Should().BeOfType(GetUnderlyingType(nullableEnumType));
        result.Should().Be(GetValue(nullableEnumType, null));

如果我返回则测试通过,(SomeEnum?) null但如果结果为则失败null

标签: c#enums.net-core-3.0

解决方案


null从方法返回ReadJson应该是您需要做的所有事情。Nullable<T>是一种值类型(即使您可以测试并分配null给它)。当它被装箱到引用类型(object例如)时,它会做以下两件事之一:

  1. 如果由Nullable<T>NOT表示的值null,那么Value就像任何其他值类型一样被装箱。
  2. 如果Nullable<T>是表示一个null值,那么结果实际上是null.

当您取消装箱(从引用类型变为Nullable<T>)时,会发生相反的情况;如果引用类型是null,则Nullable<T>创建一个新的实例并设置它没有值,但如果引用类型确实包含一个值,则Nullable<T>创建一个新实例并设置引用类型中的值成为 的当前值Nullable<T>

调用GetValueOrDefault不起作用的原因是因为Nullable<T>该方法的返回类型是T,它必须是值类型,所以它不能是null


推荐阅读