Skip to content

Latest commit

 

History

History
69 lines (57 loc) · 2.01 KB

0005. null that throws no NRE.md

File metadata and controls

69 lines (57 loc) · 2.01 KB

Это одна из задачек.

Сначала, я её загадывал в виде

// при любом ли T этот код будет выбрасывать исключение?
T x = null;
var s = x.ToString();

но потом я захотел переписать так, чтобы снипет был компилируемым:

Можно ли дописать такой TestCase, чтобы Assert зафейлился:

public class SUT<T>
{
    public T Field { get; set; }

    public string Do() => Field.ToString();
}

public class Tests
{
    [TestCase(typeof(string))]
    public void Test_Sut_Throws_NRE(Type type)
    {
        var sut = new SUT<type>();
        sut.Field = null;
        Assert.Throws<NullReferenceException>(() => sut.Do());
    }
}

Но так нельзя – [CS0118] 'type' is a variable but is used like a type

На stackoverflow нашёл рецепт

dynamic sut = Activator.CreateInstance(typeof(SUT<>).MakeGenericType(type));

и финальный вариант

Можно ли дописать такой TestCase, чтобы Assert зафейлился:

public class SUT<T>
{
    public T Field { get; set; }

    public string Do() => Field.ToString();
}

public class Tests
{
    [TestCase(typeof(string))]
    public void Test_Sut_Throws_NRE(Type type)
    {
        dynamic sut = Activator.CreateInstance(typeof(SUT<>).MakeGenericType(type));
        sut.Field = null;
        Assert.Throws<NullReferenceException>(() => sut.Do());
    }
}

А ответ – Можно, например, [TestCase(typeof(int?))], потому что Nullable реализует ToString() вот так:

public override string? ToString()
{
    return hasValue ? value.ToString() : "";
}