有些事总是自以为100%正确而无需验证

  • Nullable<T>

是为了扩展值类型不能表示空值而扩充的一个类。

	var i = new Nullable<int>(3);
            
        object box = i;//发生装箱操作,如果i有值,则把对应的Value进行box,否则将null进行box
        Console.Write(box);

然而看IL可得到这是需要box(可空类型≠引用类型,仍要box)。

    L_0000: nop 
    L_0001: ldc.i4.3 
    L_0002: newobj instance void [mscorlib]System.Nullable`1<int32>::.ctor(!0)
    L_0007: box [mscorlib]System.Nullable`1<int32>
    L_000c: stloc.0 
    L_000d: ldloc.0 
    L_000e: call void [mscorlib]System.Console::Write(object)
    L_0013: nop 

MSDN有如下表述:

在对可空类型进行装箱时,公共语言运行库自动将 Nullable 对象的基础值(而不是 Nullable 对象本身)装箱。也就是说,如果 HasValue 属性为 true,则将 Value 属性的内容装箱。如果 HasValue 属性为 false,则将 空引用(在 Visual Basic 中为 Nothing) 装箱。在对可空类型的基础值进行取消装箱时,公共语言运行库创建一个新的初始化为基础值的 Nullable 结构。

本来以为Nullable<T>既然成为可空类型,自然而然就不必box。然而细看发先Nullable<T>不过是个普通的struct而已。

  • 约束泛型struct

定义如下泛型方法,并用Struct约束泛型参数

	static void GenericVoid<T>(T i) where T : struct
        {

        }
既然Nullable<int>是struct,那么我们可以调用泛型方法:
GenericVoid<Nullable<int>>(i);
我以为这是正确的,但编译报错:类型“int?”必须是不可以为 null 值的类型才能用作泛型类型或方法“TSharp.Core.Test.ThreadClass.GenericVoid<T>(T)”中的参数“T”
泛型约束的struct意为“不可以为 null 值的类型”
 
  • 结构向接口转换需不需要box?
用代码说话:
	public interface IPoint { int X { get; } int Y { get; } }
        struct Point : IPoint
        {
            public int X { get; set; }
            public int Y { get; set; }
        }

调用代码:

            IPoint p = new Point();
            Console.Write(p);
查看IL:
.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] class TSharp.Core.Test.ThreadClass/IPoint p,
        [1] valuetype TSharp.Core.Test.ThreadClass/Point CS$0$0000)
    L_0000: nop 
    L_0001: ldloca.s CS$0$0000
    L_0003: initobj TSharp.Core.Test.ThreadClass/Point
    L_0009: ldloc.1 
    L_000a: box TSharp.Core.Test.ThreadClass/Point
    L_000f: stloc.0 
    L_0010: ldloc.0 
    L_0011: call void [mscorlib]System.Console::Write(object)
    L_0016: nop 
    L_0017: ret 
}  看到结构向接口转换需要box,看来struct还是不实现接口的好。
  • 枚举默认是Int32

枚举如果显示指定基类,则默认为Int32,且其TypeCode也为TypeCode.Int32。

            object detectorObj = MyEnum.B;
            TypeCode typeCode = System.Convert.GetTypeCode(detectorObj);
原文地址:https://www.cnblogs.com/68681395/p/1913484.html