Я потратил последние несколько дней на изучение новых C # 7.2 ref readonly
возвратов и in
параметров для структур.При этом я столкнулся с проблемой, которую я обозначил простым решением, использующим здесь модульные тесты:
https://github.com/Mike-EEE/StructureReferences
У меня есть четыре модульных теста, которые демонстрируют проблему в целом, сдва с использованием MemoryMarshal.GetReference
(область фокуса, где один тест не пройден) и два с использованием обычного назначаемого локального поля (оба теста проходят, как и ожидалось).
При всех модульных тестах я беру локально назначенный readonly struct
(с именем Structure
) с одним полем uint
и передачей его методу, который увеличивает это поле и возвращает новое struct
.
Вот что я использую для тестов, использующих MemoryMarshal
:
static ref readonly Structure Add(in Structure parameter)
{
var structure = new Structure(parameter.Count + 1);
var span = MemoryMarshal.CreateReadOnlySpan(ref structure, 0);
return ref MemoryMarshal.GetReference(span);
}
И для локально присваиваемого поля:
ref readonly Structure AddFromLocal(in Structure parameter)
{
_local = new Structure(parameter.Count + 1);
return ref _local;
}
В случае MemoryMarshal.GetReference
тест проходит, если я присваиваю результаты вызова Add
вызов метода для локальных переменных:
[Fact]
public void Assignments()
{
var one = Add(_structure);
var two = Add(one);
var three = Add(two);
three.Count.Should().Be(3);
}
Но нет, если я добавлю результаты:
[Fact]
public void Inline() // Doesn't pass.
{
Add(in Add(in Add(in _structure))).Count.Should().Be(3);
}
Мой вопрос: это ожидаемое поведение?И если так, то почему?:) Мне кажется, что если ссылка передается другому методу, который затем передается другому методу (MemoryMarshal.GetReference
), она будет беспрепятственно возвращаться обратно, как и другие тесты (и локальные полевые тесты)..
Будем весьма благодарны за любые объяснения того, почему эти два теста отличаются по своим результатам.