我有一个辅助函数,用于将
DateTimeKind
中的 DateTime?
转换为 UTC。但是,当与 DateTime
一起使用时,我收到错误 CS0266
- “无法将类型 'type1' 隐式转换为 'type2'。存在显式转换(是否缺少强制转换?)”。我以为使用 NotNullIfNotNullAttribute
会对我有帮助,但显然没有。
有人可以帮我解决这个问题吗?
public static class Utils
{
[return: NotNullIfNotNull(nameof(dt))]
public static DateTime? ToUtc(DateTime? dt) => dt?.Kind switch
{
null=>null,
DateTimeKind.Unspecified => DateTime.SpecifyKind(dt.Value, DateTimeKind.Utc),
DateTimeKind.Utc => dt,
DateTimeKind.Local => dt.Value.ToUniversalTime()
};
}
class Example {
public static void Ex1()
{
DateTime? dt0 = DateTime.Now;
DateTime? dt1 = Utils.ToUtc(dt0); // all is ok
}
public static void Ex2()
{
DateTime dt0 = DateTime.Now;
DateTime dt1 = Utils.ToUtc(dt0); // error here: Cannot implicity convert type 'System.DateTime?' to 'System.DateTime'...
}
}
NotNullIfNotNullAttribute
存在于静态代码分析中,它不能根据您的输入是否为 null 来更改方法的返回类型(即使静态已知它不为 null)。但是,您可以通过提供接受 DateTime
非空值的重载来实现您想要做的事情。像这样:
[return: NotNullIfNotNull(nameof(dt))]
public static DateTime? ToUtc(DateTime? dt) => dt?.Kind switch
{
null => null,
_ => ToUtc(dt)
};
public static DateTime ToUtc(DateTime dt) => dt.Kind switch
{
DateTimeKind.Unspecified => DateTime.SpecifyKind(dt, DateTimeKind.Utc),
DateTimeKind.Utc => dt,
DateTimeKind.Local => dt.ToUniversalTime()
};
这允许您使用
ToUtc
方法,如下所示:
DateTime? dt1 = null;
DateTime? utc1 = ToUtc(dt1);
DateTime dt2 = DateTime.Now;
DateTime utc2 = ToUtc(dt2);