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
}
我只是好奇,为什么编译器在作为扩展名调用时无法解析相同的方法?
答案 0 :(得分:3)
DateTime
明确not convertible to Nullable<DateTime>
。
C#规范,7.6.5.2扩展方法调用:
如果符合以下条件,则扩展方法符合条件:
...
如果在任何封闭的命名空间声明或编译单元中找不到候选集,则会发生编译时错误。
所以你必须明确地将DateTime
强制转换为Nullable<DateTime>
,或者从一开始就使用可空的东西:
DateTime now = DateTime.Now;
((DateTime?)now).Test();
或
DateTime? now = DateTime.Now;
now.Test();
答案 1 :(得分:1)
正如蒂姆所说的可以犯罪+1
修正:
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();
}
}
答案 2 :(得分:1)
var
不是一种类型。实际类型在编译时计算出来。如果您为DateTime.Now
设置var
,它会识别为DateTime
类型,而不是Nullable<DateTime>
,这就是它无法编译的原因。
var
个变量也称为Implicitly Typed Local Variables (C# Programming Guide)
顺便说一句,您还可以为可空类型创建通用扩展方法:
public static T? GenericMethod<T>(this T? source) where T : struct
{
//Do something
}
你可以调用任何可以为空的东西,声明它的类型:
DateTime? dateTimeNullable = DateTime.Now;
dateTimeNullable.GenericMethod();
int? intNullable = 0;
intNullable.GenericMethod();
答案 3 :(得分:0)
因为您为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
会奏效。
答案 4 :(得分:0)
现在需要使用正确的类型nullable创建变量,如下所示:
DateTime? dateTime = DateTime.Now;
dateTime.Test();