问题
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