Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有可空值类型参数的扩展方法解析_C#_Compiler Construction_Overloading_Extension Methods - Fatal编程技术网

C# 具有可空值类型参数的扩展方法解析

C# 具有可空值类型参数的扩展方法解析,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

我只是好奇,为什么编译器在作为扩展调用时不能解析相同的方法?

A
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();