2015-08-21 1 views
5

С # Согласно MSDN entry for Nothing (Visual Basic)Установить переменную VB.NET в нуль

В настоящее представляет значение по умолчанию для типа данных.

Также был отмечен some, что»... Nothing ключевого слова фактически эквивалентно С # default(T) ключевым слова».

Это дало мне некоторое аномальное поведение в многоязычном решении, над которым я работал недавно. В частности, я получаю больше, чем несколько TargetInvocationException s, которые бросаются на конец C#, когда методы async VB.NET возвращают Nothing.

Возможно ли установить переменную в проектах VB.NET на C# null и иметь возможность протестировать это значение null как на C#, так и на VB.NET.


Вот фрагмент, который не ведет себя так, как ожидалось. Проект 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 на С # null?

+0

Вы имеете в виду, что вы получаете исключение в вызове 'ToString()', потому что возвращаемое значение 'await DoSomething()' равно null? –

+5

Я мог ошибаться, но на стороне C# это похоже на то, что вы пытаетесь передать нулевое значение в '.ToString()' Который может привести к ошибке «null value», альтернативно дать нам erorr, падает на его голову "не так информативно, как" system.whatever возвращал значение X, когда он ожидал Y " – Nikerym

+1

Какое исключение' InnerException'? – Will

ответ

2

Это не из-за конверсии с Nothing в null. Вот у меня есть некоторый пример для вас, где C# принимает Nothing в null:

Vb Class Library Код:

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

C#, что Invoke Эта библиотека классов:

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, что причина для исключения вы получаете.

  • 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

Вся часть 'This help help' может быть записана' var result = (новый ClassVb(). DoSomething() ?? "") .ToString(); ' –

0

Я видел связанный с этим вопрос решен, имея VB проекта бросание «Nothing» к типу «Object», чтобы гарантировать, что это значение по умолчанию, соответствующее ссылочным типам (например, C#, NULL) и полученный на C# проекта как таковые, а значение по умолчанию некоторого типа значения (например, 0 для целочисленного типа):

params.Item2.SetResult(CObj(Nothing)) 
0

Моя ошибка стала очевидной после прочтения ООН Лаки statement:

  • null.ToString() или (null).ToString() говорит, что The operator '.' cannot be applied to operand of type '<null>'.
  • await(null) не будет разрешен C#, он говорит cannot await null.

Оказывается, потому что я установить result переменную в C# код для 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 
    } 
} 

Благодаря nikerym и Peter Duniho за их вклад. Я слишком устал от того, чтобы не спать более 20 часов, чтобы заметить, что они делают. Что бьет меня, хотя почему я использовал TargetInvokationException вместо NullReferenceException.

+0

Вы получаете' TargetInvocationException' из-за способа 'await' работает: только код до первого 'ожидания 'фактически находится в именованном методе, где вы объявили код. Остальная часть кода помещается в продолжения (фактически, один метод, инкапсулирующий конечный автомат), которые вызывается при завершении ожидаемой задачи. Если вы посмотрели на внутреннее исключение «TargetInvocationException», вы бы увидели «NullReferenceException», который фактически описал, что происходит не так. –