C# 具有可空值类型参数的扩展方法解析
我只是好奇,为什么编译器在作为扩展调用时不能解析相同的方法?AC# 具有可空值类型参数的扩展方法解析,c#,compiler-construction,overloading,extension-methods,C#,Compiler Construction,Overloading,Extension Methods,我只是好奇,为什么编译器在作为扩展调用时不能解析相同的方法?ADateTime可以显式地null C#规范,7.6.5.2扩展方法调用: 如果满足以下条件,则扩展方法合格: 当作为静态方法应用于参数时,Mj是可访问和适用的,如上图所示 存在从expr到Mj第一个参数类型的隐式标识、引用或装箱转换 如果在任何封闭的命名空间声明或编译单元中未找到候选集,则会发生编译时错误 因此,您必须显式地将DateTime强制转换为Nullable,或者从一开始就使用Nullable: public sta
DateTime
可以显式地null
C#规范,7.6.5.2扩展方法调用:
如果满足以下条件,则扩展方法合格:
- 当作为静态方法应用于参数时,Mj是可访问和适用的,如上图所示
- 存在从expr到Mj第一个参数类型的隐式标识、引用或装箱转换
DateTime
强制转换为Nullable
,或者从一开始就使用Nullable:
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
}
或
正如蒂姆所说,可以为空+1 修正:
因为您为
DateTime?
编写了扩展,而不是为DateTime
编写了扩展
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();
}
}
或
将正常工作。您现在需要使用corret类型nullable创建变量,如下所示:
var now = new DateTime?(DateTime.Now);
Extension.Test(now); // ok
now.Test(); // no compile time error
var
不是一种类型。实际类型是在编译时计算出来的。如果为var
设置DateTime.Now
,它将识别为DateTime
类型,而不是Nullable
,这就是它无法编译的原因
var
变量也称为
顺便说一下,您还可以为可为空的类型创建通用扩展方法:
DateTime? dateTime = DateTime.Now;
dateTime.Test();
只要看到错误,你的好奇心就会消失。我正要问这个问题,想知道这是否是一个编译器错误。C#语言是否有地方可以提交bug报告?该链接的可能副本表示它可以隐式转换。如果不是这样,那么标准静态方法调用也会失败。除非我误解了你。@Fearofahackplanet:也许我没有很好地表达我自己,我仍然不知道你从规范中引用的哪些资格要求没有得到满足。该方法作为静态方法可见/适用,并且存在隐式转换。。。关键点是,值类型->可空转换是隐式转换,但不是装箱转换。这就是为什么列表中的第二个要点不适用,尽管它看起来似乎应该适用。
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
DateTime? dateTime = DateTime.Now;
dateTime.Test();
public static T? GenericMethod<T>(this T? source) where T : struct
{
//Do something
}
DateTime? dateTimeNullable = DateTime.Now;
dateTimeNullable.GenericMethod();
int? intNullable = 0;
intNullable.GenericMethod();