断言变量不为空

Loo*_*oki 6 c# kotlin

我有一个类型的变量 DateTime?

在一个函数中,我检查它的存在null并希望在之后使用它而不必?.每次调用。例如在 Kotlin 中,IDE 识别出这样的检查并断言该变量不能在null之后。有没有办法在 C# 中做到这一点?

DateTime? BFreigabe = getDateTime();
if (BFreigabe == null) return false;
TimeSpan span = BFreigabe - DateTime.Now; 
//Shows Error because it.BFreigabe has the type DateTime?, even though it can't be null
Run Code Online (Sandbox Code Playgroud)

编辑:

使用时

TimeSpan span = BFreigabe.Value - DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

相反,它在这种情况下有效,因为.Value根本没有 nullsafety。但是,考虑到即使没有空检查也会编译并且只会产生错误,一般问题仍然存在。如何说服 C# 以前的可空变量不再可以为空?

编辑 2

在变量上投射 DateTime 有效。

TimeSpan span = (DateTime)BFreigabe - DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

仍然不如 Kotlin 安全,但足够相似。

Iqo*_*qon 4

如果您有之前的检查,则可以访问该值。可空类型始终具有两个属性:HasValueValue

您可以转换为DateTime(不带?)或使用 value 属性。

DateTime? BFreigabe = getDateTime();
if (!BFreigabe.HasValue == null) 
    return false;

TimeSpan span = BFreigabe.Value - DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

或者将可为空的变量存储在不可为空的变量中:

DateTime? BFreigabe = getDateTime();
if (BFreigabe.HasValue == null) 
{
    DateTime neverNull = BFreigabe.Value;
    TimeSpan span = neverNull  - DateTime.Now;
}
Run Code Online (Sandbox Code Playgroud)

这将得到编辑器的全面支持并保证没有NullReferenceExcpetion.

编辑:因为你的问题是Assert。断言通常意味着如果状态无效,我们将抛出异常。

在这种情况下,省略对 null 的检查。如果你访问var.Valuewhile varis null,这将抛出一个NullReferenceException. 这将责任转移给调用者。

另一种选择是不使用可为空变量。通过转换它(参见第二个清单)或不接受 Nullable 类型作为参数。

function TimeSpan Calc(DateTime time)
{
    // here we know for sure, that time is never null
}
Run Code Online (Sandbox Code Playgroud)