是否可以使用 NotNullIfNotNullAttribute 来避免将可空值类型的返回值转换为不可空?

问题描述 投票:0回答:1

我有一个辅助函数,用于将

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'...
  }
}
c#
1个回答
0
投票

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);
© www.soinside.com 2019 - 2024. All rights reserved.