一小时前我问了一个问题:how can I write an extension method for Enum?-Nullable<Enum>
令人惊讶的是,我得到了一个答案,告诉我我可以编写Enum
的扩展方法,它可以用于所有枚举和可空的枚举。
很酷,它有效,但是如何?
如果我理解正确,所有枚举都来自Enum
,所以这就是为什么我可以在我拥有的每个枚举中使用此扩展方法。
但是......例如,ItemType?
枚举不是枚举,而是Nullable<ItemType>
,它不是来自ItemType
也不是Enum
。<登记/>
就像List<DataReader>
不是来自DataReader
,因此无法使用DataReader
方法,但DataReader
是通用类型。
我知道Nullable<T>
类型有很多“伏都教”和句法糖,这是其中之一吗?
答案 0 :(得分:5)
扩展方法不需要类/派生/,它们只需要转换存在(更具体地说:隐式标识,引用或装箱转换;这是§7.6.5.2“扩展方法调用”)。 / p>
从Nullable<ItemType>
到System.Enum
的转换是拳击转换;与从Nullable<int>
到System.Object
的转换相同。
如果您定义了自己的结构struct Test : IMyInterface {}
,则会有从Nullable<Test>
到IMyInterface
的转换。
如果nullable为null,则来自nullables的拳击转换将返回空引用;并以其他方式包装可空的值。有关详细信息,请参阅C#规范中的§6.1.7“拳击转换”。
答案 1 :(得分:2)
它比编译器魔法更具有类型系统魔力。由于Enum
是引用类型,这意味着您传入的任何值都会被装箱(例如转换为引用)。
现在Nullable<T>
在CLR中具有特殊处理功能,如果它表示内部类型(null
)的空值或盒装值,它将产生枯萎T
,但是从来没有盒装Nullable<T>
。当然,情况恰恰相反;取消装箱到可以为空的类型会接受null
参考。
答案 2 :(得分:1)
扩展方法被转换为静态方法,第一个参数是调用方法的变量。
在Enum示例中,由于Enum是一个类(不是结构),因此扩展方法可以接受枚举的具体值(通常归结为int)或null。因此它适用于可以为空的枚举。
同样的事情对int不起作用? (可空)。如果你为int创建一个扩展方法,你将无法在Nullable上调用它(它会告诉你“无法将实例参数类型Nullable转换为int)