Передача явного приведения в качестве параметра ref (C #) - PullRequest
9 голосов
/ 30 января 2010

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

Я считал явные приведения. Допустим, у меня есть какая-то функция с параметром byte [] ref.

    public void SomeFunction(ref byte[] someBytes);

И у меня есть какой-то класс с перегруженным явным приведением.

    class SomeClass
    {
        byte[] someBytes;
        public static explicit operator byte[](SomeClass someInstance)
        {
            return someInstance.someBytes;
        }
    }

Теперь я хочу вызвать функцию с классом в качестве параметра

    SomeClass someInstance = new SomeClass();
    SomeFunction(ref (byte[]) someInstance);

Компилятор жалуется, что «аргумент ref или out должен быть присваиваемой переменной». Я не уверен, что мне просто не удается правильно помассировать компилятор или вы просто не можете этого сделать.

Я рассмотрел возвращаемое значение свойства или функции, но вы не можете передать их по ссылке (и после обучения я понимаю, почему ...)

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

РЕДАКТИРОВАТЬ: возможно, стоит отметить, что SomeFunction была написана третьей стороной, и у меня нет доступа, чтобы изменить его. Хуже того, я не думаю, что их параметр на самом деле должен быть ref ...

Ответы [ 4 ]

9 голосов
/ 30 января 2010

Приведение не является присваиваемой переменной; вы передаете возвращаемое значение из явного оператора приведения.

Вы можете создать переменную, содержащую правильно приведенное значение, перед тем как передать его в качестве ссылки:

SomeClass someInstance = new SomeClass();
byte[] someBytes = (byte[])someInstance;
SomeFunction(ref someBytes);

Обратите внимание, что теперь это переменная someBytes, которая может быть переназначена. Вам нужно будет предпринять действия, чтобы каким-либо образом переназначить someInstance.someBytes после вызова SomeFunction, если вы хотите, чтобы внутреннее значение someInstance было переназначено.

1 голос
/ 30 января 2010

Диапазон значений, которые можно использовать в качестве параметра ref в C #, ограничен тем, что позволяет CLR. Это указано в спецификации CLI в разделах 12.4.1.5.2 и 12.1.6.1 и включает

  • Аргумент текущего метода
  • Локальная переменная
  • Член Поле объекта
  • Статическое поле
  • Элемент массива

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

1 голос
/ 30 января 2010

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

Рассмотрим следующий код, если то, что вы просили, было разрешено:

public void SomeFunction(ref byte[] someBytes)
{
    someBytes = new byte[] { 1, 2, 3 };
}

SomeClass someInstance = new SomeClass();
SomeFunction(ref (byte[]) someInstance);
// uh-oh, what is "someInstance" now?

Почему аргумент помечен как "ref", какую проблему вы пытаетесь решить здесь?

0 голосов
/ 13 октября 2017

Вам действительно нужно привести параметр ref? В моем случае что-то вроде этого работает нормально.

byte[] someInstance = (byte[])new SomeClass(); 
SomeFunction(ref someInstance);
...