2014-03-03 31 views
12

我们都知道VB的Nothing与C#的null类似,但并不相同。 (如果你不知道的是,看看this answer第一。)是否有一个VB.NET表达式* always *会产生null?

只是出于好奇,我想知道以下几点:

是否有一个VB.NET表达式总是产生null


举一个具体的例子,采取以下语句:

Dim o As Object = If(myBool, 5, ...) 

是否有可能有东西来取代...,这样o5myBool是真实的,Nothing/nullmyBool是假的?

明显的解决方案,这是行不通的:

  • Nothing问题(见上面的链接的答案),
  • DirectCast(Nothing, Object)(投用选项严格在编译时错误),
  • DirectCast(Nothing, Integer?)适用于本示例,但不起作用一般(如果在此示例中将5替换为5.0,则需要修改转换)。

明显的解决方法(将不能算作答复):

  • 声明一个Object变量或字段,其设置为Nothing并使用该对...
  • 定义总是方法或属性返回Nothing,
  • DirectCast第二个参数(5)到Object

注意:上面的示例只是一个示例。问题本身以粗体书写。

+0

你想要一个适用于参考和值类型的单线程吗?如果值类型不可为空会怎么样?你能显示这个代码的_usage_吗? – CodeCaster

+3

你的问题不是很清楚,你为什么总是需要'null'?使用可空类型而不是对象有什么问题?如果你的例子是\t可互换提供了一个更好的例子,'Int32?'不是一个选项。 –

+0

@TimSchmelter:我认为编写一个自动化的C# - > VB.NET转换器可能会有用,但主要我只是好奇。我不明白这个问题如何不清楚:“VB.NET表达式”是明确定义的,表达式的期望返回值在问题中清楚地陈述。 – Heinzi

回答

13

第一个答案我给错过了一些分,但是这应该这样做:

Dim o As Object = If(myBool, 5, DirectCast(Nullable.GetUnderlyingType(GetType(Integer)), Object)) 

它使用的事实,如果你传递一个类型,是不是一个空值Nullable.GetUnderlyingType将返回一个空引用类型 - 其中Integer不是。还有其他替代方案,例如Type.GetElementType()或者GetType(Object).BaseType

我已经检查过,它适用于第二个操作数的多种不同类型。

这是有点恼人,你必须强制转换为Object ......我仍然在工作的替代品为...

+0

@ Heinzi:啊 - 这一点的目的对我来说并不明显。你把它变成一个通用的方法呢?(这当然会比所有这些搞乱更简单。) –

+0

@Heinzi:实际上,如果你把它改成5.0,这个代码仍然可以工作。 –

+0

@Heinzi:啊 - 我没有没有选项严格打开,忽略我以前的评论:( –

7

简单的答案是,没有。 VB.NET中没有表达式只返回null。如您所知,当编译器使用三元运算符分析命令时,它会根据两个输入来推断输出类型。如果两个输入之一是Nothing,则它必须完全依赖其他参数。因此,在VB中做“正确”的方法。NET是先投其他参数Object,从而迫使操作的输出是一个Object

Dim o As Object = If(myBool, DirectCast(5, Object), Nothing) 

但是,如果你真的需要一个在线表达它,本身,始终计算为null ,你总是可以通过调用lambda表达式,像这样做:

Dim o As Object = If(myBool, 5.0, (Function() Nothing).Invoke()) 

这句法应该在任何情况下工作,总是会导致Nothing而不是潜在地导致默认值。

+0

是的。但请参阅“明显的解决方法(不会算作答案)”的第3点“。 – Heinzi

+0

糟糕。快速阅读问题我猜:( –

+0

我更新了我的答案,以包含另一个,尽管很丑,解决方案,哪种*符合您的标准。 –

0

System.DBNull.Value是最有可能你追求的。

扩展,从技术共和国:

...下面的C#代码确定一个字符串值为null:

string sTest = "Test"; if (sTest == null) { Console.WriteLine("sTest is Null"); } 

此代码的工作没有任何问题与C#,但没有VB.NET等价于null关键字。相反,VB.NET使用Nothing关键字。下面的代码演示了它的用法:

Dim sTest As String 
If (sTest Is Nothing) Then 
    Console.WriteLine("sTest is Null") 
End If 

混乱的另一个领域的事实,VB.NET不把无效和没有平等地茎;因此,VB.NET程序员可能需要检查两个值。

支持的变化可能会引起混淆,但开发人员很少能同时在两种语言中开发。另一方面,Microsoft提供了使用空值的统一方法:基本System.Convert名称空间包含DBNull对象。

DBNull

使用该DBNull类的指示不存在一个已知的值的。 虽然Microsoft文档说它通常位于数据库 应用程序中,但您也可以将它用于任何类型的数据。

If (sTest.Equals(System.DBNull.Value) Then 
    Console.WriteLine("sTest is Null") 
End If 

- 逐字从Working with Null values in the .NET Framework

+1

'System.DBNull.Value IsNot Nothing'。 – nmclean

0

您可以创建一个自己(选择一个不同的名称功能,如果你喜欢):

Private Function ValueOrNull(expression As Boolean, value As Object) As Object 
    If expression Then Return value 
    Return Nothing 
End Function 

用法:

Dim myBool As Boolean 
Dim o As Object = ValueOrNull(myBool, 5) 

适用于任何类型,包括您的示例5.0

相关问题