【问题标题】:Why c# null can implicit convert to System.Nullable<T>, but can not a self defined Nullable<T> [duplicate]为什么 c# null 可以隐式转换为 System.Nullable<T>,但不能自定义 Nullable<T> [重复]
【发布时间】:2015-04-11 04:15:19
【问题描述】:

为什么null可以像这样隐式转换为System.Nullable&lt;T&gt;

int? val = null;

但是自定义Nullable&lt;T&gt;(从.net 参考源修改)不能分配null,是不是有一些编译器魔法?谁能告诉我更多的内部实现?

[Serializable]
public struct Nullable<T> where T : struct
{
    private bool hasValue;
    internal T value;

    public Nullable(T value)
    {
        this.value = value;
        this.hasValue = true;
    }

    public bool HasValue
    {
        get
        {
            return hasValue;
        }
    }

    public T Value
    {
        get
        {
            if (!HasValue)
            {
                throw new Exception();
            }
            return value;
        }
    }

    public T GetValueOrDefault()
    {
        return value;
    }

    public T GetValueOrDefault(T defaultValue)
    {
        return HasValue ? value : defaultValue;
    }

    public override bool Equals(object other)
    {
        if (!HasValue) return other == null;
        if (other == null) return false;
        return value.Equals(other);
    }

    public override int GetHashCode()
    {
        return HasValue ? value.GetHashCode() : 0;
    }

    public override string ToString()
    {
        return HasValue ? value.ToString() : "";
    }

    public static implicit operator Nullable<T>(T value)
    {
        return new Nullable<T>(value);
    }

    public static explicit operator T(Nullable<T> value)
    {
        return value.Value;
    }
}

下面的测试代码,编译错误

Nullable<int> x = null; //ERROR Cannot convert null to 'Nullable<int>' because it is a non-nullable value type

【问题讨论】:

  • 因为 System.Nullable 在 C# 语言中得到特殊处理。
  • @default.kramer 有什么详细信息吗?
  • @Asad 这是一个 Nullable 装箱或拆箱问题,所以我认为它不重复
  • 还有其他特殊处理的例子如lifted operators and conversions

标签: c# .net


【解决方案1】:

C# 5.0 规范的第 6.1.5 节:

6.1.5 空字面量转换
从 null 文字到任何可为 null 的类型都存在隐式转换。此转换生成给定可为空类型的空值(第 4.1.10 节)。

请注意,这种编译器提供的隐式转换只存在于可为空的类型。您自定义的 Nullable&lt;T&gt; 不是 C# 规范定义的可为空的类型。它只是您声明的一些结构,它具有内置 Nullable&lt;T&gt; 类型的许多功能(在引用的第 4.1.10 节中描述),但根据 C# 中的定义,它实际上不是“可空的” .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多