Int I=7;
Int ? j= null;
在这里,我们可以将引用类型(空)分配给值类型(j)。 由于此可为空的东西位于System.Nullable命名空间下,该名称空间是一种结构。 怎么可能。?
答案 0 :(得分:2)
int ? j= null
是语法糖。
此:
private void Foo()
{
int? i = null;
}
此:
private void Foo()
{
Nullable<int> i = null;
}
这:
private void Foo()
{
Nullable<int> i = new Nullable<int>();
}
编译为:
.method private hidebysig instance void Foo() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> i)
IL_0000: nop
IL_0001: ldloca.s i
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0009: ret
} // end of method Program::Foo
其中
IL_0001: ldloca.s i
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int32>
表示初始化结构实例。
因此,没有空引用,并且存在一个对象。无需HasValue
即可访问其只读属性NullReferenceException
。
int? i = null;
Console.WriteLine(i.HasValue);
给予
False
和
Console.WriteLine(i.Value);
不是引发NullReferenceException,而是引发 InvalidOperationException 。
尽管
Console.WriteLine(i.GetType());
引发NullReferenceException。
长话短说,对于Nullable<T>
或T?
null
表示不是 null-reference
,而是实例 Nullable<T>
中的HasValue
设置为false。
但是
如果您正在寻找 WAY
如何在c#中将引用类型分配给结构
尝试一下:
class Program
{
private static void Main(string[] args)
{
Struct<int> @struct = new Class<int>(-1);
Class<int> @class = new Struct<int>(-1);
}
}
class Class<T>
{
public T Value { get; }
public Class(T value) => Value = value;
public static implicit operator Struct<T>(Class<T> instance) => new Struct<T>(instance.Value);
}
struct Struct<T>
{
public T Value { get; }
public Struct(T value) => Value = value;
public static implicit operator Class<T>(Struct<T> instance) => new Class<T>(instance.Value);
}
请记住,它看起来只是作业,但是在真正的作业发生之前进行了投射。
答案 1 :(得分:1)
C#规范在这一点上很明确:null
关键字表示没有类型的表达式。它既不是引用类型,也不是值类型,也不是指针类型。但是,该表达式可转换为所有这些类型。不需要编译器将所有表达式归类为具有类型,事实上,事实并非如此。
任何类型都可以包含null
1)对于引用类型:
如果引用类型变量包含null
,则表示它未指向堆上的任何内容。引用类型变量存储在堆栈中,并且可以包含null
或对实际堆对象的引用。
2)对于值类型::如果可为空的值类型变量包含null
,则表示该变量自身不包含任何值。值类型(大多数情况下)存储在堆栈上,并且可以在自身或null
中包含直接值。