尝试在 C# 中将强制转换运算符实现为可空类型时出错

我目前正在创建一个struct Nullsafe<T>将包装引用类型(因此T:class)并以与Nullable<T> struct. 关键是模仿Option<T>F# 中的功能。


我打算在需要特别注意空值的方法中使用类型。例如,假设我有一个引用类型class Foo和以下代码:


class Bar

{

    public void DoSomethingWithFoo(Nullsafe<Foo> foo);

}

由于我创建了一个隐式转换运算符 from Tto 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 社区 2017 v15.8.1

.NET Sdk v2.1.400(如图所示 dotnet --version

该项目是一个多面向不同 .NET 框架版本的库 - 从 net20 到 netstandard2.0


青春有我
浏览 291回答 2
2回答

江户川乱折腾

根据Roslyn 中的代码,尚不清楚这是否绝对是有意的。该行为来自编译Nullable器从转换中涉及的类型中剥离包装器,以便正确地捕获从Nullable<Foo>to 的标识转换Nullable<Foo>- 但在您的情况下,类型在剥离之前是不同的,因此应该允许它。您可以在存储库中打开一个问题- 我找不到任何已经打开的问题。更熟悉编译器设计的人可以参与进来,但它看起来确实像一个错误。

千巷猫影

观察到的行为实际上是有意和确认的。创建了一个语言设计讨论线程,以解决是否应更改此行为以支持上述用例,或者以其他方式提供更好的编译器错误消息以显示。
打开App,查看更多内容
随时随地看视频慕课网APP