我试图让一个函数返回一个带有命名字段的ValueTuple,而不是'Item1','Item2'等。
看着the documentation,我具有以下功能:
Public Function MyFunction() as (Success as Boolean, Results as Boolean)
Return (True, False)
end Function
Dim test = MyFunction()
If test.Success Then
'Do something with test.Result
End If
这可以编译,但是如果我在if语句上放置一个断点并查看“ test”,它将显示其字段为“ Item1”和“ Item2”。它还会在运行时引发以下异常:
System.MissingMemberException: 'Public member 'Success' on type 'ValueTuple(Of Boolean,Boolean)' not found.'
此外,该文档仅在“ Option Strict Off”下起作用,但是我们在代码中将其打开,并且该代码在Option Strict On下无法编译。
严格启用选项后,我尝试了以下操作:
Dim test as ValueTuple(Of Success as Boolean, Results as Boolean) = MyFunction()
但是,如果未定义“成功”,它会给出编译时错误。
我的语法是否错误?在设置Option Strict On的情况下,如何定义一个用作命名字段的函数输出的变量?
如果相关,我的项目在.NET 4.6.1中,但是我已经使用NuGet包管理器添加了ValueTuple包。
答案 0 :(得分:1)
在您的问题中,您会遇到一些令人困惑的事情,但是大多数问题很容易解决。
在.NET框架中,Tuples提供了与匿名类型类似的功能,但是它们的实现方式有所不同,我认为这种差异在这里引起混乱。
让我们看一下这段代码:
Dim x = (Success := True, Results := False)
Dim y = New With {.Success = True, .Results = False}
第一个是元组,第二个是匿名类型。
它们都可以以类似的方式使用:
Console.WriteLine(x.Success)
Console.WriteLine(y.Success)
Console.WriteLine(x.Results)
Console.WriteLine(y.Results)
在引擎盖下,它们的结构不同。
这里是反编译的相同代码(因为我的工具生成的都是C#):
(bool, bool) valueTuple = (true, false);
VB$AnonymousType_0<bool, bool> vB$AnonymousType_ = new VB$AnonymousType_0<bool, bool>(Success: true, Results: false);
Console.WriteLine(valueTuple.Item1);
Console.WriteLine(vB$AnonymousType_.Success);
Console.WriteLine(valueTuple.Item2);
Console.WriteLine(vB$AnonymousType_.Results);
请注意,元组具有属性Item1
和Item2
(实际上是字段),但是匿名类型具有属性Success
和Results
。
为元组字段命名只是编译器的ery俩!反映类型不会返回源中使用的名称。
匿名类型的确会创建具有属性的对象,这些属性具有源中可反射的名称。
尝试一下:
Console.WriteLine(String.Join(", ", x.GetType().GetFields().Select(Function(z) z.Name)))
Console.WriteLine(String.Join(", ", y.GetType().GetProperties().Select(Function(z) z.Name)))
我得到:
Item1, Item2 Success, Results
元组方法允许我这样写:
Dim w As (Apple As Boolean, Banana As Boolean) = x
Console.WriteLine(w.Apple)
Console.WriteLine(w.Banana)
使用匿名类型不能做到这一点。
在您的问题中,您说您在运行代码时遇到运行时错误。我没有在计算机上得到它。您的第一批代码运行良好。