Вернуть Enum of null динамически, используя Type - PullRequest
1 голос
/ 20 января 2020

В сериализаторе у меня есть

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] значение null?

Я пытался Activator.CreateInstance(objectType);, который возвращает null вместо (SomeEnum?)null

Я также пытался

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

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

, который также возвращает ноль

Можно ли вернуть (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

1 Ответ

0 голосов
/ 20 января 2020

Возвращение null из метода ReadJson должно быть всем, что вам нужно сделать. Nullable<T> - это тип значения (даже если вы можете проверить его и присвоить null). Когда он упакован в ссылочный тип (например, object), он делает одно из двух:

  1. Если значение, представленное Nullable<T>, НЕ равно null, тогда Value упакован так же, как и любой другой тип значения.
  2. Если Nullable<T> представляет значение null, то в результате получается null.

. обратное происходит при распаковке (переход от ссылочного типа к Nullable<T>); если ссылочный тип равен null, то создается новый экземпляр Nullable<T>, который устанавливается таким образом, что у него нет значения, но если ссылочный тип действительно содержит значение, то создается новый экземпляр Nullable<T> и значение в ссылочном типе установлено как текущее значение Nullable<T>.

Причина, по которой вызов GetValueOrDefault не работает, заключается в том, что для Nullable<T> тип возвращаемого значения этого метода T, который должен быть типом значения, поэтому он не может быть null.

...