【问题标题】:How to affect to a boolean value the result of a boolean? expression如何将布尔值的结果影响到布尔值?表达
【发布时间】:2019-06-11 10:18:06
【问题描述】:

我想在 VB 中编写相当于 C# 中的代码:

bool? a = whatever;
bool b= (a==true);

VB 编译器不接受这个:

Dim a As Boolean?
Dim b As Boolean = (a = True)

我想在这种情况下,它将(a = True) 解释为一种矫揉造作,而我希望它被解释为一种表达方式。 (a == True) 显然是语法错误。

【问题讨论】:

  • 你的意思是bool? a = true; bool b = (a == true);需要赋值。在 VB.Net 中它可以是Dim a As Boolean? = True Dim b As Boolean = (a.Value = True)。但是你应该先测试a.HasValue
  • 在 C# 中,如果将 Nullable 与非 Nullable 进行比较,则结果是不可为空的。在 VB.NET 中,结果是 Nullable。这就是为什么您不能将其分配给非 Nullable 变量的原因。原因是VB.NET设计者说,如果Nothing的意思是“我不知道这是什么”那么每次比较的结果也是未知的(related

标签: vb.net nullable


【解决方案1】:

您需要注意 0、Nothing 和 vbNull 之间的区别。 0 是布尔值的默认值。 vbNull 是保留的 Null 值,应转换为 1。 几乎在所有情况下都不会引发异常

Dim a As Boolean? = Nothing
Dim b As Boolean? = vbNull
Dim c As Boolean = vbNull
Dim d As Boolean

Print(a = True) 'will throw an Exception
Print(b = True) 'will return True (as vbNull = Int(1))
Print(c = True) 'will return True as the ? is unnecessary on a Boolean as vbNull = Int(1)
Print(d = True) 'will return False as the default value of a Boolean is 0
Print(a.GetValueOrDefault) 'will return False as this handles the Nothing case.

在使用未分配的值时,您应该始终首先检查 Nothing(或者只是遵循良好做法并在使用之前设置值)。

    Dim a As Boolean?
    Dim b As Boolean = IIf(IsNothing(a), False, a)

如果 a 为 Nothing,则返回 False,否则返回 A。

只有在测试 Nothing 之后才能测试 vbNull,因为 Nothing 在所有值上都会返回错误。下面的代码将在 Nothing 或 vbNull 或其他情况下返回 False。

    Dim a As Boolean?
    Dim b As Boolean = IIf(IsNothing(a), False, IIf(a = vbNull, False, a))

注意:您不能使用下面的代码,因为测试 a = vbNull 将反对 Nothing ,这将引发异常。

Or(IsNothing(a), a = vbNull) 

我也会避免在任何实际应用程序中使用 GetValueOrDefault,因为当您开始使用更复杂的数据类型时,默认值不会那么简单,而且您会得到意想不到的结果。恕我直言,测试 IsNothing(或 Object = Nothing,Object Is Nothing)比依赖数据类型的怪癖好得多。

最佳做法是确保 a 具有价值,您可以使用

    Dim a As Boolean? = New Boolean()
    Dim b As Boolean = a

我之所以说这是最佳实践,是因为它可以转换为所有类,而不仅仅是布尔值。注意到这对于布尔值来说是多余的。

希望这会有所帮助。

【讨论】:

  • 你为什么要提vbNull,而原来的问题没有问到它,而且与它无关?此外,由于类型安全问题,我强烈建议停止使用 IIf --- 你应该更喜欢在引入 IIf 函数时 VBA 中不存在的三元 If --- 和 @987654330 @ 函数应替换为 Is Nothing。我建议编辑您的答案以使其更有用。
  • 我记得,vbNull 是基于 VBA 的 VB 版本的产物,它具有 Null 作为可能的 Variant 值以支持数据库中的空值。它与当前的 .NET 可空对象正交,不应直接与它们(或 Boolean 变量)混合。事实上,如果你尝试使用Option Strict On 编译你的代码,它会因为试图将VariantType (vbNull) 类型的值分配给Boolean?Boolean 类型的变量而拒绝。
  • OP 对为什么遇到语法错误感到困惑,因此解释了 VB 与 C++ 的一些差异。在“IIFs”上注明,这是一个让具有 C++ 经验的人保持代码简短和可读性的演示。所有的 VB 都是基于“VB”的。 VBA 和 VB.Net 是 VB 的扩展,与 VB6 一起出现(我 16 年前开始编程)。
  • 问题在于vbNull 与OP 的问题无关,因为它只是作为帮助将pre-.NET 软件移植到VB.NET 的桥梁而存在。它与Nullable 的行为无关,更容易混淆而不是帮助,特别是如果它被错误地使用(即除了检查Variant 的值类型之外,将它用于任何事情 , 即使那样我还是建议使用IsDbNull 而不是比较VarTypevbNull)。
【解决方案2】:

你也可以使用CBool

Dim a As Boolean?
Dim b As Boolean = CBool(a = True)

【讨论】:

  • 如果aNothing,则会抛出System.InvalidOperationException
  • @MatSnow 布尔值的默认值为False。所以它不可能是Nothing,除非它被手动设置为Nothing
  • Nullable Booleans 可以是 null,(未设置值)。您应该将代码更改为Dim b As Boolean = If(a.HasValue, a.Value = True, False)
  • @preciousbetine 是的,Boolean 的默认值是 False,是的,它不能是 Nothing,但不,它不能设置为 NothingDim a As Boolean = Nothing 将运行,但它将默认值分配给a,即False。 (请参阅分析器 here) - 但 a 是一个可为空的布尔值 (Boolean?),因此它可以Nothing。这就是问题的全部意义所在。尝试运行你的代码,你会明白我的意思......
【解决方案3】:

你可以使用GetValueOrDefault-方法:

Dim a As Boolean?
Dim b As Boolean = a.GetValueOrDefault()

【讨论】:

  • 这个很优雅:)
猜你喜欢
  • 2015-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
相关资源
最近更新 更多