【发布时间】:2008-12-09 20:32:41
【问题描述】:
如何在 VB 中为泛型创建默认值?在 C# 中我可以调用:
T variable = default(T);
- 如何在 VB 中做到这一点?
- 如果这只是返回 null (C#) 或什么都不返回 (vb),那么值类型会发生什么?
- 有没有办法为自定义类型指定默认值?例如,如果我希望默认值等同于在我的类上调用无参数构造函数。
【问题讨论】:
如何在 VB 中为泛型创建默认值?在 C# 中我可以调用:
T variable = default(T);
【问题讨论】:
Dim variable As T
' or '
Dim variable As T = Nothing
' or '
Dim variable As New T()
请注意,后者仅在您为泛型类型指定 Structure 约束时才有效(对于引用类型,VB 中的 New T() 与 C# 中的 default(T) 不同)。
对于值类型,结构的所有成员都被“清空”,即所有引用类型成员都设置为null (Nothing),而所有值类型又被清空。
不,因为string 是一个引用类型,它确实不导致"" 用于其他答案中建议的字符串。
不,没有办法指定这一点。 Stack Overflow 上已经有一些关于此的主题,例如here。 Jon 发布了一个 excellent explanation 这是为什么。
【讨论】:
New 或 Structure 必须在约束中指定。
T 具有New 约束并且在运行时恰好是引用类型,那么Dim variable As New T() 肯定会做其他事情(即创建一个实例并将引用返回到它)比第一个(返回Nothing)。此外,2015 年将出现一个新版本的 VB.NET,其中值类型可以具有无参数的实例构造函数,因此这些值类型也会发生变化。
实际上,人们这样做的正确方法是将null (Nothing) 类型转换为您的泛型类型,如下所示:
Dim tmpObj As T = CType(Nothing, T)
如果要返回泛型的默认值,只需返回 CType(Nothing, T)
【讨论】:
不是真正的 VB 人,我在最初的答案中犯了一些错误,康拉德让我直截了当。原始答案如下,但我想根据 Konrad 的输入更新我的答案以使其正确。
正如 Konrad 所说,default(T) 和 Nothing 实际上对于值类型和引用类型都是等价的。正确的 VB 代码应如下所示,在这种情况下,您将获得与我的 C# 代码完全相同的行为:
Function ReturnSomething(Of T)() As T
Return Nothing
End Function
Function DoSomething(Of T)()
Dim x as T = Nothing;
If x = Nothing Then
Console.WriteLine("x is default.")
Else
Console.WriteLine("x has a value.")
End If
似乎没有与default(T) 等效的VB。但是根据this post,与C#不同,如果T是值类型,在VB中你仍然可以使用Nothing,这在大多数情况下语义相同。
您在使用Nothing 而通常使用default(T) 时遇到问题的大地方是您是否需要在代码中对其进行测试。考虑以下 C# 代码:
T ReturnSomething<T>()
{
return default(T);
}
void DoSomething<T>()
{
T x = default(T);
if(x == default(T))
Console.WriteLine("x is default.");
else
Console.WriteLine("x has a value.");
}
这样翻译成VB:
Function ReturnSomething(Of T)() As T
Return Nothing
End Function
Function DoSomething(Of T)()
Dim x as T = Nothing;
If x Is Nothing Then
Console.WriteLine("x is default.")
Else
Console.WriteLine("x has a value.")
End If
End Function
如果T 是引用类型,则两个版本对ReturnSomething 和DoSomething 的行为完全相同。然而,如果T 是一个值类型,ReturnSomething 对任何一种语言的行为都完全相同,但DoSomething 将打印“x 是默认值”。在 C# 版本中,但“x 有值”。在VB版本中。
【讨论】:
default(T) 和 Nothing完全相同相同。另外,您的代码翻译不正确,相关的 VB 代码应为x = Nothing,效果很好。 Is 等价于 C# 的 object.ReferenceEquals。