Могу ли я передавать примитивные типы по ссылке в С#?

Я знаю, что сложные типы передаются ссылкой в ​​С#, а примитивные типы передаются значением. Могу ли я передавать примитивные типы по ссылке в С#?

Update:

Спасибо за ответы, но мой пример?

void test(object x) {

}

long y = 1;

test(ref y);

Это исключение: Тип аргумента 'ref' не соответствует типу параметра

Ответы

Ответ 1

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

static void Main(string[] args)
{
    var value = 10;
    var boxed = (object)value;
    TakesValueByRef(ref boxed);
    value = (int)boxed;
    // value now contains 5.
}

static void TakesValueByRef(ref object value)
{
    value = 5;
}

Просто имейте в виду эту ужасную практику и рискованную (из-за исключений из-за исключения) для этого.

Ответ 2

Здесь есть несколько разных вопросов.

Можно ли передавать примитивные типы по ссылке в С#?

Прежде всего, позвольте убедиться, что жаргон здесь правильный. Неясно, что вы подразумеваете под "примитивным типом". Вы имеете в виду "встроенный в runtime" тип типа int или long? Вы имеете в виду любой тип значения независимо от того, является ли он встроенным или определяемым пользователем?

Я собираюсь предположить, что ваш вопрос на самом деле

Можно ли передавать типы значений по ссылке в С#?

Типы значений называются типами значений, поскольку они передаются по значению. Типы ссылок называются ссылочными типами, поскольку они передаются по ссылке. Таким образом, казалось бы, ответ по определению, нет.

Однако это не так просто.

Сначала вы можете поместить экземпляр типа значения в экземпляр ссылочного типа, поместив его в бокс:

decimal d = 123.4m; // 128 bit immutable decimal structure
object o1 = d; // 32/64 bit reference to 128 bit decimal
object o2 = o1; // refers to the same decimal
M(o2); // passes a reference to the decimal.
o2 = 456.78m; // does NOT change d or o1

Во-вторых, вы можете превратить экземпляр типа значения в ссылку, создав массив:

decimal[] ds1 = new decimal[1] { 123.4m }; 
decimal[] ds2 = ds1;
ds2[0] = 456.7m; // does change ds1[0]; ds1 and ds2 refer to the same array

В-третьих, вы можете передать ссылку на переменную (а не значение - переменную), используя ключевое слово ref:

decimal d = 123.4m;
M(ref d);
...
void M(ref decimal x)
{ // x and d refer to the same variable now; a change to one changes the other

Попытка передать ref long методу, который принимает объект ref, вызывает ошибку компиляции: Тип аргумента 'ref' не соответствует типу параметра

Правильно. Тип переменных с обеих сторон должен точно соответствовать. См. Этот вопрос для деталей:

Почему полиморфизм "ref" и "out" не поддерживается?

Ответ 3

Конечно, вы можете:

public void MyFunction(ref int a)
{
}

Ответ 4

Просто используйте модификатор параметра ref или out.

void myMethod(ref int myValue) ...

ref - 2 пути. out - 1 способ.

Ответ 5

Вы можете использовать слово ref рядом с параметром в определении функции.

public void func(ref int a)
{
    //do stuff
}

public void doStuf()
{
    int a = 5;
    func(ref a);
}

Ответ 6

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

Если вы украшаете параметр ref или out, а затем, изменяя то, что у вас есть внутри, этот метод также влияет на переданную переменную.

// Doesn't change obj1
void DoesntChange(object obj)
{
    obj = new object(); // Assigns a new object to the local variable obj.
}

var obj1 = new object();
DoesntChange(obj1);

// Will change obj2
void WillChange(ref object obj)
{
    obj = new object(); // Assigns a new object to the local ref variable obj
                        // and changes the obj2 variable to point at the new object.
}

var obj2 = new object();
WillChange(ref obj2);

Чтобы изменить параметр переменной примитивного типа внутри метода и сохранить изменение на сайте вызова, он должен быть передан с помощью ref или out.