[英]Implicit operator isn't called for default of struct in C#
I'm implementing a C# variant of Haskell's Maybe and came across a weird issue where null
and default
has different implication on the value returned from an implicit
conversion.我正在实施 Haskell 的 Maybe 的 C# 变体,遇到一个奇怪的问题,其中
null
和default
对implicit
转换返回的值有不同的含义。
public class TestClass
{
public void Test()
{
Maybe<string> valueDefault = default;
Maybe<string> valueNull = null;
Maybe<string> valueFoobar = "foobar";
Console.WriteLine($"Default: (Some {valueDefault.Some}, None {valueDefault.None}");
Console.WriteLine($"Null: (Some {valueNull.Some}, None {valueNull.None}");
Console.WriteLine($"Foobar: (Some {valueFoobar.Some}, None {valueFoobar.None}");
}
}
public struct Maybe<T>
{
public T Some { get; private set; }
public bool None { get; private set; }
public static implicit operator Maybe<T>(T value)
{
return new Maybe<T>() {
Some = value,
None = value == null
};
}
}
The output being: output 是:
Default: (Some, None False)
默认值:(一些,无假)
Null: (Some, None True)
Null:(一些,不正确)
Foobar: (Some foobar, None False)
Foobar:(一些foobar,没有假)
I was expecting both valueDefault
and valueNull
to be equal.我期望
valueDefault
和valueNull
相等。 But seems that null
is converted while default
isn't.但似乎
null
已转换,而default
值未转换。 I fixed the issue by replacing None with HasSome with a reversed boolean condition, but still the question remains.我通过将 None 替换为具有反向 boolean 条件的 HasSome 来解决问题,但问题仍然存在。
Why is null and default treated differently?为什么 null 和 default 被区别对待?
Every type has a default value, including Maybe<T>
.每种类型都有一个默认值,包括
Maybe<T>
。 See this page for a list.请参阅此页面以获取列表。
Maybe<string> valueDefault = default;
will assign the default value of Maybe<string>
to valueDefault
.会将
Maybe<string>
的默认值分配给valueDefault
。 What's the default value of Maybe<string>
? Maybe<string>
的默认值是多少? According to that page, since Maybe<string>
is a struct, its default value is:根据那个页面,因为
Maybe<string>
是一个结构,它的默认值是:
The value produced by setting all value-type fields to their default values and all reference-type fields to null.
通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为 null 生成的值。
So it's an instance of Maybe<string>
with Some
being null
and None
being false
.所以它是
Maybe<string>
的一个实例,其中Some
是null
而None
是false
。 false
is the default value of bool
. false
是bool
的默认值。
The compiler doesn't try to use the default value of string
, since that requires a further conversion to Maybe<string>
.编译器不会尝试使用
string
的默认值,因为这需要进一步转换为Maybe<string>
。 If it can just use the default value of Maybe<string>
, why go the extra trouble, right?如果它可以直接使用
Maybe<string>
的默认值,为什么 go 会很麻烦,对吧?
You can force it to though:你可以强制它:
Maybe<string> valueDefault = default(string);
null
, on the other hand, gets converted to Maybe<string>
because null
is not a valid value of Maybe<string>
(structs can't be null,), so the compiler deduces that you must mean null as string
, and does the implicit conversion.另一方面,
null
被转换为Maybe<string>
因为null
不是Maybe<string>
的有效值(结构不能是 null,),因此编译器推断您必须null as string
,并且确实隐式转换。
You might know this already, but you seem to be reinventing Nullable<T>
您可能已经知道这一点,但您似乎正在重新发明
Nullable<T>
default
always fills the memory of the struct with zero bytes. default
总是用零字节填充结构的 memory。 null
is not a valid value for a value type, so the compiler discovers the implicit (Maybe<string>)(string)null
cast. null
不是值类型的有效值,因此编译器发现隐式(Maybe<string>)(string)null
转换。
Perhaps you could replace with;也许您可以替换为;
public struct Maybe<T>
{
public T Some { get; private set; }
public bool None => Some == null;
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.