根据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
时,一切都会落在它的头上。
如何在不导致异常的情况下有效SetResult
到Nothing
,或者我怎样才能SetResult
到C#' null
?
答案 0 :(得分:2)
这不是因为从Nothing
转换为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
时,其明确转换为null
但.ToString()
方法或await()
无法处理null
&#{1}} 39; s你获得例外的原因。
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();
答案 1 :(得分:0)
我已经看到通过让VB项目将'Nothing'强制转换为'Object'类型来解决相关问题,以确保它是与引用类型相对应的默认值(例如,C#null)并由C#项目接收因此,而不是某个值类型的默认值(例如,0表示整数类型):
params.Item2.SetResult(CObj(Nothing))
答案 2 :(得分:0)
阅读不幸运的statement后,我的错误变得明显:
- c#不允许
null.ToString()
或(null).ToString()
表示The operator '.' cannot be applied to operand of type '<null>'
。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
}
}
感谢nikerym和Peter Duniho的贡献。我太累了,不能熬夜20多个小时才能注意到他们正在制造的这一点。但是我的成绩是TargetInvokationException
而不是NullReferenceException
。