С# 6/С++ ref ключевое слово

Я попробовал VS2015 с моим существующим решением, и у меня появились некоторые допустимые новые ошибки (например, недостижимый код, который компилятор не заметил ранее), но я также получаю ошибку, например, в этой строке:

bool bWasAlreadyLocked = false;
oEnv.LockDoc(oWarnings, oEventDoc, ref bWasAlreadyLocked);

Я получаю следующую ошибку:

Ошибка CS1503 Аргумент 3: невозможно преобразовать из 'ref bool [mscorlib, Версия = 4.0.0.0, Культура = нейтраль, PublicKeyToken = b77a5c561934e089] 'to 'ref bool [mscorlib, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089] '

Я не понимаю, почему это запустило бы эту ошибку, очевидно, что типы соответствуют. Является ли это ошибкой в ​​новом компиляторе или изменилось поведение ключевого слова ref?

Функция в этом случае является функцией С++, которая импортируется в С#, используя класс С#, полученный из класса С++. Это подпись:

void CBkgDocEnvX::LockDoc(
CFIWarningList ^oWarnings,
CBaseDoc ^oBaseDoc,
// Output
bool %rbWasAlreadyLocked)

Хорошо бы упомянуть, что я решил использовать VS2013 С++-компилятор для источников С++ в этом решении, поэтому сторона С++ должна быть такой же, как раньше. Я предполагаю, что что-то во взаимодействии между С# и С++ изменилось.

Ответы

Ответ 1

Оказывается, эта ошибка может быть исправлена ​​путем явного добавления атрибута out к параметру.

Добавление [Out] к параметру ref, по-видимому, помогает новому компилятору С# распознавать, что они являются теми же типами и принимают их. Теперь методы в нашем взаимодействии выглядят следующим образом:

using namespace System::Runtime::InteropServices;

...

virtual void LockDoc(
   CFIWarningList ^oWarnings,
   CBaseDoc ^oBaseDoc,
// Output
   [Out] bool %rbWasAlreadyLocked
   ) override;

Ответ 2

Вы должны проверить этот пункт, чтобы быть уверенным.

  • Только L-значения могут передаваться по ссылке. L-значение - это переменные и другие выражения, которые могут отображаться в левой части задания. К ним относятся, в том числе, локальные жители, обращения к полям, разметки указателей и обращения к элементам массива. L-значения не включают доступа к ресурсам, которые не имеют идентифицируемого машинного адреса, и не включают поля только для чтения, которые ограничены средой CLR.
  • Параметры Ref не могут быть объектом метода расширения. Вызовы методов расширения являются дорогостоящими для типов значений, поскольку параметр "this" копируется по значению. Это также означает, что типы значений can not имеют изменяемые методы расширения. Это прямо контрастирует с методами экземпляра, которые передают параметр типа "this" по ссылке.
  • Параметры параметров нельзя использовать в функциях перегрузки оператора.

Вы можете найти дополнительную информацию здесь.

Ответ 3

Я получаю такие ошибки компилятора, когда два проекта имеют несовместимые типы. Часто Visual Studio позволяет мне добавить ссылку на проект Portable Class Library (или проект .NET 4.0), даже если ссылка на сборку не поддерживается ссылочным типом профиля .NET проекта.

Наиболее распространенным явлением для меня является использование проекта .NET 4.0 и попытка ссылаться на проект библиотеки вероятных классов, который указывает .NET 4.5 в настройках профиля, а не на старую версию .NET 4. Когда я ссылаюсь на сборку PCL из моего проекта .NET 4.0, я продолжаю получать полную поддержку intellisense (например, при редактировании исходного кода intellisense отображает все пространства имен, классы и свойства, содержащиеся внутри ссылки, на которые ссылаются). Но во время компиляции я получаю такая же ошибка, которую вы получаете; более конкретно, когда я компилирую решение, компиляция указывает на несоответствие библиотеки, но перечисляет ту же самую библиотеку, версию и открытый ключ, которые, по ее словам, ищут.

Проверьте свойства проекта, убедитесь, что они совместимы.

Ответ 4

Вы можете попробовать использовать тип данных Object вместо Boolean. После этого вы можете разобрать его на Boolean.