Ошибка при попытке реализовать оператор приведения к обнуляемому типу в C # - PullRequest
0 голосов
/ 08 сентября 2018

В настоящее время я создаю struct Nullsafe<T>, который будет оборачивать ссылочный тип (следовательно, T:class) и вести себя аналогично Nullable<T> struct. Суть в том, чтобы подражать чему-то близкому к тому, что делает Option<T> в F #.

Я намереваюсь использовать тип в методах, которые мне нужны для особой заботы о пустых значениях. Например, предположим, что у меня есть ссылочный тип class Foo и следующий код:

class Bar
{
    public void DoSomethingWithFoo(Nullsafe<Foo> foo);
}

Поскольку я создал неявный оператор приведения от T до Nullsafe<T>, приведенный ниже код будет работать нормально:

Bar bar = new Bar();

Foo nullFoo = null;
bar.DoSomethingWithFoo(nullFoo);

Foo someFoo = new Foo();
bar.DoSomethingWithFoo(someFoo);

Тип Nullsafe<T> является структурой (разработанной специально для того, чтобы исключить непосредственную передачу любых null значений), поэтому кто-то может написать следующий фрагмент:

Nullable<Nullsafe<Foo>> nullableNullsafeFoo = null;
// and later
bar.DoSomethingWithFoo(nullableNullsafeFoo);

Фрагмент, конечно, не будет работать.

Итак, я подумал, что было бы легко создать оператор приведения изнутри моей структуры Nullsafe<T>, которая будет обрабатывать такие выражения, как указано выше:

public static implicit operator Nullsafe<T>(Nullable<Nullsafe<T>> nv) => nv.GetValueOrDefault();

К сожалению, это не скомпилируется. Компилятор, похоже, не делает различий между типами Nullsafe<T> и Nullable<Nullsafe<T>> и выдает мне сообщение:

Вышеупомянутое ограничение компилятора, или это преднамеренно предполагаемое поведение? Если да, есть ли какие-нибудь известные обходные пути?

ошибка CS0555: Пользовательский оператор не может взять объект вложенного типа и преобразовать в объект вложенного типа

Я использую:

  • Visual Studio Community 2017 v15.8.1
  • .NET Sdk v2.1.400 (как показано dotnet --version

Проект представляет собой библиотеку, нацеленную на разные версии платформы .NET - от net20 до netstandard2.0

Обновление

Вышеупомянутое ограничение компилятора, или это намеренно предполагаемое поведение?

Похоже, что это действительно результат информации о типе разборки компилятором, описанной другим пользователем Исаак ван Бакель .

Если так, есть ли известные обходные пути?

Делая, как он советовал, я отправил вопрос на платформу Рослин.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Наблюдаемое поведение фактически предназначено и подтверждено .

Проект языка Тема обсуждения была создана для решения вопроса о том, следует ли изменить это поведение в пользу сценариев использования, подобных описанным выше, или иным образом улучшить отображение сообщения об ошибке компилятора.

0 голосов
/ 10 сентября 2018

Не ясно, если это определенно предназначено, на основе кода в Roslyn . Поведение происходит из-за того, что компилятор удаляет оболочку Nullable из типов, участвующих в приведении, чтобы правильно отловить приведение идентификаторов от Nullable<Foo> до Nullable<Foo>, но в вашем случае типы перед извлечением различаются, поэтому следует быть разрешенным.

Вы можете открыть вопрос в хранилище - я не смог найти ни одного уже открытого. Кто-то, более знакомый с дизайном компилятора, сможет взвесить, но это похоже на ошибку.

...