- 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: nopMSDN有如下表述:
在对可空类型进行装箱时,公共语言运行库自动将 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);