Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 隐式运算符isn';t调用C中的默认结构#_C#_Implicit Conversion - Fatal编程技术网

C# 隐式运算符isn';t调用C中的默认结构#

C# 隐式运算符isn';t调用C中的默认结构#,c#,implicit-conversion,C#,Implicit Conversion,我正在实现Haskell's Maybe的C#变体,遇到了一个奇怪的问题,null和default对隐式转换返回的值有不同的含义 public class TestClass { public void Test() { Maybe<string> valueDefault = default; Maybe<string> valueNull = null; Maybe<string> value

我正在实现Haskell's Maybe的C#变体,遇到了一个奇怪的问题,
null
default
隐式转换返回的值有不同的含义

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
        };
    }
}
公共类TestClass
{
公开无效测试()
{
可能valueDefault=默认值;
可能valueNull=null;
可能是valueFoobar=“foobar”;
WriteLine($”Default:(Some{valueDefault.Some},None{valueDefault.None});
WriteLine($“Null:$Some{valueNull.Some},None{valueNull.None}”);
WriteLine($“Foobar:(Some{valueFoobar.Some},None{valueFoobar.None}”);
}
}
可能是公共结构
{
公共T某些{get;私有集;}
公共bool None{get;private set;}
公共静态隐式运算符(T值)
{
返回新的Maybe(){
一些=价值,
无=值==null
};
}
}
输出为:

默认值:(部分,无错误)

Null:(部分,非真)

Foobar:(一些Foobar,没有错误)

我原以为
valueDefault
valueNull
是相等的。但似乎
null
被转换了,而
default
没有。我用一个反向布尔条件将None替换为HasSome,解决了这个问题,但问题仍然存在

为什么null和default的处理方式不同?

default
总是用零字节填充结构的内存。
null
不是值类型的有效值,因此编译器会发现隐式的
(可能)(字符串)null
强制转换

也许你可以用

公共结构
{
公共T某些{get;私有集;}
公共bool None=>Some==null;
...
每种类型都有一个默认值,包括
可能
。有关列表,请参阅

Maybe-valueDefault=default;
Maybe
的默认值分配给
valueDefault
Maybe
的默认值是什么?根据该页面,由于
Maybe
是一个结构,其默认值是:

通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为null而生成的值

因此,它是
的一个实例,可能
部分
null
false
false
bool
的默认值

编译器不会尝试使用默认值
string
,因为这需要进一步转换到
Maybe
。如果它可以使用默认值
Maybe
,为什么还要额外麻烦呢

您可以强制它执行以下操作:

Maybe<string> valueDefault = default(string);
Maybe valueDefault=default(字符串);
另一方面,
null
被转换为
Maybe
,因为
null
不是
Maybe
的有效值(structs不能为null!),因此编译器推断您的意思必须是
null as string
,并进行隐式转换

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
        };
    }
}


您可能已经知道这一点,但您似乎正在重新设计

@JeremyLakeman right,因为引用类型可以是
null
。由编译器将null作为字符串推导为
null是非常有意义的。但是
null
不符合我的目的,因为我非常希望在结构内部强制null验证n通过
选项
的方式,可以潜在地防止消费者抛出
NullReferenceException
。这对于
可能
之类的值类型不是很有用,因为您永远无法将其设置为
等于
的值。对于将来的参考,您可能通过调试代码并查看隐式运算符在
Maybe valueDefault=default;
@devNull:从问题的标题判断,我认为OP可能理解“隐式运算符实际上没有被调用”?我承认,这很难说。当然,如果他们真的理解了这一点,那么他们为什么会对
默认值
的含义感到惊讶也不清楚。我发现很难确切地说出OP无法理解的部分。希望评论和回答中有足够的信息,让他们得到他们想要的,不管是什么。@PeterDuniho True,我试图找到一种方法来强制
default
调用隐式运算符。而我应该在结构中设置适当的默认值
None