将VB.NET变量设置为C#< null

时间:2015-08-21 04:26:50

标签: c# vb.net null nothing

根据MSDN entry for Nothing (Visual Basic)

  

Nothing 表示数据类型的默认值。

some也注意到{" ... Nothing关键字实际上等同于C#的default(T)关键字"。

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

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

这是一个行为不符合预期的片段。 C#项目导入VB.NET项目作为参考。

VB.NET Side

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#Side

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
}

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

如何在不导致异常的情况下有效SetResultNothing,或者我怎样才能SetResult到C#' null

3 个答案:

答案 0 :(得分:2)

这不是因为从Nothing转换为null。在这里,我有一些示例,其中C#接受Nothingnull

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时,其明确转换为null.ToString()方法或await()无法处理null&#{1}} 39; s你获得例外的原因。

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

  • {li>

    await(null) c#不允许cannot await null

这可能会对您有所帮助:

ClassVb classLibObj = new ClassVb();
var temp = classLibObj.Dosomething();
var result = temp == null ? "" : temp.ToString();  

答案 1 :(得分:0)

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

params.Item2.SetResult(CObj(Nothing))

答案 2 :(得分:0)

阅读不幸运的statement后,我的错误变得明显:

  
      
  • null.ToString()(null).ToString()表示The operator '.' cannot be applied to operand of type '<null>'
  •   c#不允许
  • await(null)cannot await null
  •   

事实证明,因为我已将C#代码中的result变量设置为string,所以无法从Object转换(如在VB.NET和#39中) ; s返回类型Task(Of Object)),无需.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多个小时才能注意到他们正在制造的这一点。但是我的成绩是TargetInvokationException而不是NullReferenceException