Extension method resolution with nullable value type params

喜你入骨 提交于 2019-12-31 00:03:29

问题


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
}

I'm just curious, why is the compiler not able to resolve the same method when called as an extension?


回答1:


A DateTime is not convertible to Nullable<DateTime> explicitly.

The C# specification, 7.6.5.2 Extension method invocations:

An extension method is eligible if:

  • Mj is accessible and applicable when applied to the arguments as a static method as shown above
  • An implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.

...

If no candidate set is found in any enclosing namespace declaration or compilation unit, a compile-time error occurs.

So you have to cast the DateTime to Nullable<DateTime> explicitly or use a nullable from the beginning:

DateTime now = DateTime.Now;
((DateTime?)now).Test();

or

DateTime? now = DateTime.Now;
now.Test();



回答2:


As Tim said nullable +1

Fix:

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



回答3:


var isn't a type. The actual type is figured out at compile-time. If you set DateTime.Now for a var, it will recognize as a DateTime type, not a Nullable<DateTime>, and that's why it doesn't compile.

var variables are also known as Implicitly Typed Local Variables (C# Programming Guide)

By the way, you can also create a generic extension method for nullable types:

public static T? GenericMethod<T>(this T? source) where T : struct
{
    //Do something
}

and you can call whatever is nullable, declaring its type:

DateTime? dateTimeNullable = DateTime.Now;
dateTimeNullable.GenericMethod();

int? intNullable = 0;
intNullable.GenericMethod();



回答4:


Because you wrote an extension for DateTime? and not for DateTime.

        DateTime? now = DateTime.Now;
        Extension.Test(now); // ok
        now.Test(); // no compile time error

or

        var now = new DateTime?(DateTime.Now);
        Extension.Test(now); // ok
        now.Test(); // no compile time error

will work.




回答5:


you need to create your variable now with the corret type nullable like this:

 DateTime? dateTime = DateTime.Now;
 dateTime.Test();


来源:https://stackoverflow.com/questions/22015929/extension-method-resolution-with-nullable-value-type-params

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!