5

根据MSDN条目Nothing(Visual Basic)

没有任何东西代表数据类型的默认值。

也有人注意到 ...Nothing关键字实际上等同于 C# 的default(T)关键字”。

这在我最近一直在研究的多语言解决方案中给了我一些异常行为。具体来说,TargetInvocationException当 VB.NET 异步方法返回时,我在 C# 端抛出了多个 s Nothing

是否可以将 VB.NET 项目中的变量设置为 C#,null并能够null在 C# 和 VB.NET 中测试该值。


这是一个未按预期运行的代码段。C# 项目导入 VB.NET 项目作为参考。

VB.NET 端

Public Function DoSomething() As Task(Of Object)
    Dim tcs = New TaskCompletionSource(Of Object)
    Dim params = Tuple.Create("parameters", tcs)

    AnotherMethod(params)

    Return tcs.Task
End Function

Public Sub AnotherMethod(params As Tuple(Of String, TaskCompletionSource(Of Object))
    ' do some activities
    If result = "Success" Then
        params.Item2.SetResult("we were successful") ' result can also be of different type
    Else
        params.Item2.SetResult(Nothing)  ' could this be the source of the exception?
    End If
End Sub

C# 端

public async void AwaitSomething1()
{
    var result = "";
    result = (await DoSomething()).ToString(); // fails if Result is Nothing
}

public async void AwaitSomething2()
{
    var result = "";
    result = (string)(await DoSomething());    // fails if Result is Nothing
}

public async void AwaitSomething3()
{
    var task = DoSomething();
    await task;                                // also fails if Result is Nothing
}

AnotherMethodVB.NET成功时不会抛出异常。但是,当它不成功并且tcs' 的结果设置为 时Nothing,一切都落在了它的头上。

我怎样才能有效SetResultNothing不导致异常,否则,我怎么能SetResult到 C# 的null

4

3 回答 3

2

这不是因为从Nothingto转换null。在这里,我为您提供了一些 C# 接受Nothing的示例null

Vb 类库代码:

Public Class ClassVb
    Public Function Dosomething() As Task(Of Object)
        Return Nothing
    End Function
End Class

调用此类库的 C#:

using vbclassLib;
  class Program
    {
     static void Main(string[] args)
        {
            ClassVb classLibObj = new ClassVb();
            var result = classLibObj.Dosomething();//result=null
        }
    } 

哪个工作正常并给出result=null,即,Nothing is converted as null

让我来看看你的场景:

在您的场景中,当函​​数返回时,Nothing它肯定会转换为nullbut.ToString()方法或await()无法处理null,这就是您遇到异常的原因。

  • null.ToString()或者 (null).ToString()The operator '.' cannot be applied to operand of type '<null>'

  • await(null)不会被允许的c#,它说cannot await null

这可能会帮助您:

ClassVb classLibObj = new ClassVb();
var temp = classLibObj.Dosomething();
var result = temp == null ? "" : temp.ToString();  
于 2015-08-21T05:32:42.593 回答
0

我已经看到通过让 VB 项目将“Nothing”转换为“Object”类型来解决相关问题,以确保它是对应于引用类型(例如,C# null)并由 C# 项目接收的默认值,而不是某些值类型的默认值(例如,整数类型为 0):

params.Item2.SetResult(CObj(Nothing))
于 2015-08-21T05:37:39.367 回答
0

阅读 un-lucky 的声明后,我的错误变得明显:

  • null.ToString()或者(null).ToString()The operator '.' cannot be applied to operand of type '<null>'
  • await(null)c# 不允许,它说cannot await null.

事实证明,因为我已将resultC# 代码中的变量设置为string,所以无法从Object(如在 VB.NET 的返回类型中Task(Of Object))进行转换,而无需执行 a.ToString()(string)(await Method()). 使用这两个过程中的任何一个也会导致NullReferenceException.

Task<object>我终于能够通过首先将返回的变量分配给一个变量然后null在等待后检查它的结果来找出我做错了什么。因此,我完成了符合我目的的这样的代码。

public class CSharpClass
{
    public async void AwaitSomething()
    {
        var task = new VbNetClass().DoSomething();
        await task;
        // test task.Result for null
        var result = (task.Result ?? "method was unsuccessful").ToString();

        // rest of code follows
    }
}

感谢nikerymPeter Duniho的贡献。我熬夜超过 20 个小时太累了,没注意到他们的观点。不过,让我失望的是为什么我有 aTargetInvokationException而不是NullReferenceException.

于 2015-08-21T07:36:28.820 回答