Nano Hash - криптовалюты, майнинг, программирование

VB.NET Upcasted ByRef ведет себя как ByVal

Я столкнулся со странной ситуацией. Приведенный ниже код завершается ошибкой, потому что удаленный объект все еще пытается получить доступ к вызывающей подпрограмме, даже если вызываемая подпрограмма установила переданному параметру новое значение.

Sub Foo(ByRef astream as Stream)
    'do stuff
    astream.Dispose()
    astream = New MemoryStream()
End Sub

Sub Other()
    Dim memstream as New MemoryStream()
    Foo(CType(memstream, Stream))
    memstream.Position = 0' <- FAILS with Object Disposed!
End Sub

Однако это удается:

Sub Foo(ByRef astream as MemoryStream)
    'do stuff
    astream.Dispose()
    astream = New MemoryStream()
End Sub

Sub Other()
    Dim memstream as New MemoryStream()
    Foo(memstream)
    memstream.Position = 0' <- This works now!
End Sub

Итак, почему первый не работает, когда задействован upcasting, а второй работает?

РЕДАКТИРОВАТЬ: Забыл упомянуть, что я использую июньскую Roslyn CTP для VS 2013 (на случай, если это ошибка).

Спасибо.

21.07.2014

  • +1 Я использую VS 2010, и поведение такое же. 21.07.2014
  • @TimSchmelter Спасибо, что разъяснили это. Я предполагаю, что это по дизайну тогда. Но почему? 21.07.2014

Ответы:


1
  Foo(CType(memstream, Stream))

Выражение CType() создает временную переменную. Это тот, который обновляется. Другими словами, компилятор генерирует такой код:

  Dim $Temp = CType(memstream, Stream)
  Foo($Temp)

Очевидно, что это не приведет к обновлению вашей переменной memstream. Вместо этого вам понадобится именованная переменная:

  Dim temp = CType(memstream, Stream)
  Foo(temp)
  memstream = temp

Или просто полностью избегайте использования CType(), поскольку в этом нет необходимости. Вы избегаете такого рода потерь, используя функцию вместо подпрограммы:

  Function Foo(ByVal astream as Stream) As MemoryStream
     ''do stuff
     astream.Dispose()
     Return New MemoryStream()
  End Function

Хотя это довольно странный код.

И последнее, но не менее важное: вы можете заставить компилятор выдать для этого диагностику. Project + Properties, вкладка Compile, раздел конфигурации Warnings. Измените «Неявное преобразование» с «Нет» на «Предупреждение». Это, однако, имеет тенденцию быть шумным предупреждением, типичный код VB.NET имеет много неявных преобразований.

21.07.2014
  • Большое тебе спасибо! Что объясняет его! Я не могу использовать ваше предложение функции, потому что мой фактический код более сложен, чем тот, что я здесь разместил, и это уже функция, которая возвращает что-то еще, поэтому я не могу вернуть из нее поток. Думаю, я буду придерживаться объявления новой именованной переменной, как вы предложили. 21.07.2014
  • О, кстати... Было бы иначе, если бы вместо этого использовался DirectCast? 22.07.2014
  • Нет, это все-таки выражение. Вы продолжаете настаивать на необходимости приведения, это настоятельно предполагает, что вместо этого вам действительно следует использовать функцию. Как написано в вашем фрагменте, аргумент, который вы передаете, может быть только Stream или MemoryStream. Все остальное будет лаять на вас. 22.07.2014
  • Я понимаю. Спасибо. Ну, в моем случае это тоже может быть FileStream. Я просто не включил его в свою выборку, чтобы не усложнять. 22.07.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..