Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 可为空的<;T>;幕后打字?_C#_.net - Fatal编程技术网

C# 可为空的<;T>;幕后打字?

C# 可为空的<;T>;幕后打字?,c#,.net,C#,.net,我很想知道可空类型在幕后是如何工作的。是否正在创建一个可能值为null的新对象(对象可以赋值为null) 在这个例子中,我们使用了一个null值,当你给它赋值时,它们是从一个对象到一个int的隐式转换,还是从一个int到另一个int的隐式转换 我也知道如何手动创建它,使用可空类型而不是自己创建它是否有好处?可空类型是一个由两个字段组成的结构:abool和aT。当值为null时,bool为false,T为默认值。当值不为null时,bool为true 与自己实现功能相比,使用Nullable有两个

我很想知道可空类型在幕后是如何工作的。是否正在创建一个可能值为null的新对象(对象可以赋值为null)

在这个例子中,我们使用了一个null值,当你给它赋值时,它们是从一个对象到一个int的隐式转换,还是从一个int到另一个int的隐式转换


我也知道如何手动创建它,使用可空类型而不是自己创建它是否有好处?

可空类型是一个由两个字段组成的结构:a
bool
和a
T
。当值为null时,bool为false,T为默认值。当值不为null时,bool为true


与自己实现功能相比,使用
Nullable
有两个主要好处。还有语言支持,如Chaospanion的回答中更详细地描述的,还有一个事实,即装箱(转换为
对象
)将自动删除可空的“包装器”,留下空引用或普通的T对象。z

可空的
被实现为覆盖
等于()的结构
如果
HasValue
false
则表现为
null
。有一个从
T
T?
的隐式转换,还有一个在另一个方向的显式转换,它抛出if
!HasValue

实际上非常简单。编译器将帮助您掌握语法

// this
int? x = null;
// Transformed to this
int? x = new Nullable<int>()

// this
if (x == null) return;
// Transformed to this
if (!x.HasValue) return;

// this
if (x == 2) return;
// Transformed to this
if (x.GetValueOrDefault() == 2 && x.HasValue) return;
//这个
智力?x=零;
//转变成这样
智力?x=新的可空()
//这个
如果(x==null)返回;
//转变成这样
如果(!x.HasValue)返回;
//这个
如果(x==2)返回;
//转变成这样
如果(x.getValuerDefault()==2&&x.HasValue)返回;
以下是针对Nullable运行.Net Reflector的(整理过的)代码

[Serializable, StructLayout(LayoutKind.Sequential), TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")]
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 this.hasValue;
    }
}

public T Value
{
    get
    {
        if (!this.HasValue)
        {
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
        }
        return this.value;
    }
}

public T GetValueOrDefault()
{
    return this.value;
}

public T GetValueOrDefault(T defaultValue)
{
    if (!this.HasValue)
    {
        return defaultValue;
    }
    return this.value;
}

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

public override int GetHashCode()
{
    if (!this.HasValue)
    {
        return 0;
    }
    return this.value.GetHashCode();
}

public override string ToString()
{
    if (!this.HasValue)
    {
        return "";
    }
    return this.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;
}
}
[Serializable,StructLayout(LayoutKind.Sequential),TypeDependency(“System.Collections.Generic.NullableComparer`1”),TypeDependency(“System.Collections.Generic.NullableEqualityComparer`1”)]
公共结构为null,其中T:struct
{
私有布尔值;
内部T值;
公共可为空(T值)
{
这个值=值;
this.hasValue=true;
}
公共布尔值
{
得到
{
返回此.hasValue;
}
}
公共价值
{
得到
{
如果(!this.HasValue)
{
ThrowHelper.ThrowInvalidOperationException(异常资源.无效操作\u NoValue);
}
返回此.value;
}
}
公共T GetValuerDefault()
{
返回此.value;
}
公共T获取值默认值(T默认值)
{
如果(!this.HasValue)
{
返回默认值;
}
返回此.value;
}
公共覆盖布尔等于(对象其他)
{
如果(!this.HasValue)
{
返回(其他==null);
}
如果(其他==null)
{
返回false;
}
返回此.value.Equals(其他);
}
公共覆盖int GetHashCode()
{
如果(!this.HasValue)
{
返回0;
}
返回此.value.GetHashCode();
}
公共重写字符串ToString()
{
如果(!this.HasValue)
{
返回“”;
}
返回此.value.ToString();
}
公共静态隐式运算符可为null(T值)
{
返回新的可为空(值);
}
公共静态显式运算符T(可空值)
{
返回值;
}
}

@Rfvgyhn我真的不明白这是怎么一个重复。他们想知道int和nullable之间的区别。这不是我要问的。@Frank不如你发表一个答案来帮助我和社区,而不是试图结束我的问题。显然,这里有一些答案在你提到的问题中没有提到或解释。这也是第二次,他们没有问我要什么。+1的伟大解释。你有没有关于这方面的参考资料,我可以更详细地了解它?具体是在哪方面?解释了装箱问题。+1很好的答案,发现Nullable在引擎盖下由什么组成很有趣。“当值为null时,bool为false,T为默认值。”默认值是什么?因为当我使用下面的代码
bool?x=零;如果(x.Value){}
我得到InvalidOperationException。如果指定了默认值,那么为什么会出现错误?为什么不返回默认值呢?如果HasValue属性为false,则表示对象的值未定义。这是我在Microsoft文档的定义中找到的。您能(在reflector中)验证这一点吗?至少最后一行应该是不必要的,因为
隐式运算符Nullable
(请参阅)我在linqpad中运行了此操作,并确认最后一行包含对这两个属性的调用。这与==本身的实现方式有关,即使是使用另一个可为null的<代码>如果(x==y)变成
如果(x.GetValueOrDefault()==y.GetValueOrDefault()&&x.HasValue==y.HasValue)
@BlueRaja-Danny Pflughoeft-就是这样的情况。是这样吗?哪里是
hasValue
set?hasValue默认为False,在构造函数中仅设置为True,我知道,它是不可变的。不知道我在想什么。。。谢谢+这太棒了。谢谢你的代码,这很有意义。