具有可空值类型参数的扩展方法解析
public static class Extension { public static void Test(this DateTime? dt) { } } void Main() { var now = DateTime.Now; Extension.Test(now); // ok now.Test(); // compile time error }
我只是好奇,为什么编译器在作为扩展名调用时无法解析相同的方法?
DateTime
不能显式转换为 Nullable
。
C#规范,7.6.5.2扩展方法调用:
在以下情况下,扩展方法符
- 当作为静态方法应用于参数时,Mj是可访问且适用的,如上所示
- 从expr到Mj的第一个参数的类型存在隐式标识,引用或装箱转换。
…
如果在任何封闭的名称空间声明或编译单元中找不到候选集,则会发生编译时错误。
因此,您必须显式地将DateTime
为Nullable
或者从头开始使用可为空的:
DateTime now = DateTime.Now; ((DateTime?)now).Test();
要么
DateTime? now = DateTime.Now; now.Test();
正如蒂姆所说,可以为空
固定:
public static class Extension { public static void Test(this DateTime? dt) { } } public class Program { private void Main() { DateTime? now = DateTime.Now; Extension.Test(now); now.Test(); } }
var
不是一种类型。 实际类型在编译时计算出来。 如果为var
设置DateTime.Now
,它将识别为DateTime
类型,而不是Nullable
,这就是它无法编译的原因。
var
变量也称为隐式类型局部变量(C#编程指南)
顺便说一句,您还可以为可空类型创建通用扩展方法:
public static T? GenericMethod(this T? source) where T : struct { //Do something }
你可以调用任何可以为空的东西,声明它的类型:
DateTime? dateTimeNullable = DateTime.Now; dateTimeNullable.GenericMethod(); int? intNullable = 0; intNullable.GenericMethod();
因为你为DateTime?
写了一个扩展名DateTime?
而不是DateTime
。
DateTime? now = DateTime.Now; Extension.Test(now); // ok now.Test(); // no compile time error
要么
var now = new DateTime?(DateTime.Now); Extension.Test(now); // ok now.Test(); // no compile time error
将工作。
你现在需要创建你的变量,其中corret类型为nullable,如下所示:
DateTime? dateTime = DateTime.Now; dateTime.Test();