Передача параметров методу

134
29 ноября 2019, 01:40

сидел я значится и грыз один ресурс под названием metanit раздел C#, после прочтения одной темы собственно она напиасана в заглавии мне казалось всё простым и понятным, но перечитав эту же главу после прочтения аналогичного раздела в книге Шиллта кажется слегка тронулся умом. Собственно сам вопрос что именно происходит когда передаём переменную по значению и по ссылке, и тот же вопрос относительно передачи объектов классов и тех же строк и типа object. Моя дурацкая гипотеза такова что при передаче переменной по значению выполняется присвоение этой самой переменной параметру(да я читал и знаю что передаётся копия переменной), но собственно у Шилдта написано мол значение аргумента копируется в параметр,а по-поводу передачи по ссылке здесь можете уже наверное совсем сойти с ума от моих рассуждений,но я всё таки озвучу их,собственно как я понимаю что такое переменная,переменная есть именованная область памяти ну и собственно имея этой переменной это её адрес в памяти и когда мы передаём ссылку на это область то фактически говорим что вот по такому-то адресу положить такое-то значение,то есть получится так что в параметр метода будет передан адрес по которому лежит значение и можно будет его изменить внутри метода Собственно вот немного кода так обычно лучше получается объяснить:

public int AdditionRef(ref int x, int y)
{
return x = x + y;  /* Я считаю что в иксе будет адрес аргумента использованного при вызове то бишь чисто в 16-ой форме что-то в духе 0x14453454 */
}
public int AdditionVal (int x, int y)
{
 return x+y /*А здесь я считаю выполнится присвоение параметрам аргументов при вызове.*/
}

То есть при вызове AdditionVal(a,b) в моём представлении произойдёт что в духе x=a,y=b А теперь про объкты методов тут уже не буду прям так сильно расписывать и скажу вот как: при передаче объекта в качестве аргумента методу происходит присвоение аргумента параметру.Предположим у нас есть объект класса Person и метод принимающий в качестве параметра объекты такового

class Person
{
 pubic int Age;
 public string Name;
public static void ChangeP(Person p)
{
  p.Age = 18;
  p.Name = "Павлик";
}
}

что-то я немного задолбался тут типа метод main и в нём создаём объект Peson p1 и кидаем его в метод ChangeP и я думаю что здесь произойдёт следующие p = p1 Далее при передаче по ссылке тот же класс тот же метод но с модификатором ref и я хотел бы узначть что будет с тем параметром p ведь как написано у Шилдта,Троелсена на metanit'e будет передана сама ссылка и как мне кажется параметр p вообще куда-то в сторону уходит и работаем с той ссылкой что передали. P.S простите что много букв и местами написано так что у вас может возникнуть желание меня четвертовать, но это дело не даёт мне покоя

Answer 1

Сам ref это передача обьекта по этой же ссылке. Если ты обращаешся к обьекту переданому по ref ты обращаешся к самому обьекту, а не к его pointer-у (адресу памяти)

Теперь по на примере:

public int AdditionRef(ref int x, int y)
{
    return x = x + y;
    // в иксе будет ЗНАЧЕНИЕ обьекта, а не ссылка на область памяти. Фактически ты передал 
    // инстанс обьекта а не его копию (копия передалась бы без слова ref)
    // т.к. здесь есть ref -- если ты изменишь значение X внутри этого метода, то значение 
    // икса изменится и ВНЕ  этого метода.
}

Твоя проблема в том, что ты воспринял ref как *.

ref - принудительно передает оригинальный value-type обьект в метод. То есть передает в другой метод ЭТОТ ЖЕ ИНСТАНС обьекта вместо создания копии.

* - передает значение ссылки на область памяти (pointer). Вот в ней хранился бы адрес в памяти в духе 0x14453454 . Но шарп запрещает использование этого ключевого знака в коде по-дефолту в целях безопасности. Для его использования нужно врубить в проэте unsafe code support и использовать модификатор unsafe возле класса/метода.

А вот пример работы с поинтером ( * ) за который ты принял референс ( ref ) :

unsafe class TestClass
{
    static void Main()
    {
        char theChar = 'Z';
        char* pChar = &theChar;
        System.Console.WriteLine("Value of theChar = {0}", theChar);
        System.Console.WriteLine("Address of theChar = {0:X2}",(int)pChar);
    }
}

Выведет в консоль:

Value of theChar = Z

Address of theChar = 12F718

READ ALSO
Реализация превью чужого окна

Реализация превью чужого окна

Как реализовать превью чужих окон в своём окне? Аналогично нажатию alt+tab

96
Ошибка миграции There is already an object named 'Permission' in the database

Ошибка миграции There is already an object named 'Permission' in the database

Не понимаю, постоянно ловлю ошибки например

123
Обновление Chart в отдельном потоке

Обновление Chart в отдельном потоке

На форме имеется 5 элементов chart, их нужно обновлять каждый определённый промежуток времени, при этом ,чтобы в этот момент с окном программы...

116
Обработка команд по WebSocket c# ASP.NET Core

Обработка команд по WebSocket c# ASP.NET Core

Как подключить методы к вебсокету чтобы пользователь мог ими пользоваться по API, и можно ли для этого использовать signalr?

107