Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Аргументы методов в C# по ссылке или по значению?

#c_sharp #clr #теория


Насколько я знаю в сишарпе аргументы передаются по значению. Но тогда я не понимаю
вот чего. Я сейчас смотрю код, в котором присутствует такой метод:

public static string GetRequest(string Url, string UserAgent = "", CookieDictionary
Cookies = null, ProxyType ProxyProto = ProxyType.None, string ProxyString = "")
{
    ...

    try
    {
        HttpResponse response = request.Get(Url);
        Cookies = response.Cookies;
        response_html = response.ToString();
    } 

}


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

CookieDictionary cookies = new CookieDictionary();
string url = "http://mail.ru";
string resp = Web.GetRequest(url, "", cookies, Web.ProxyType.HTTP, "127.0.0.1:8888");
resp = Web.GetRequest(url, "", cookies, Web.ProxyType.HTTP, "127.0.0.1:8888");


При втором запросе передаются куки, которые получены при первом. Кроме того в методе
я пробовал добавлять свои куки через Cookies.Add() и они присутствовали в следующих
вопросах. Почему это работает?
    


Ответы

Ответ 1



В C# действительно аргументы передаются по значению. Вопрос только, что это за аргументы. Если это аргументы — числа или похожие объекты (они называются типами-значениями), то они передаются таки как есть — передаётся их копия. А если аргументы — объекты классов (они называются ссылочными типами), то по значению передаётся ссылка (то есть как бы указатель, если вы знакомы с C) на объект, а не копия самого объекта. По копии ссылки объект доступен точно так же, как и по оригиналу, и это тот же самый объект. Почему это сделано так? Дело в том, что не все объекты можно просто склонировать. И даже если это можно, что делать со ссылками на другие объекты, которые содержит данный объект? Клонировать все внутренние объекты? Это слишком долго и слишком сложно (например, что делать, если ссылки выстраиваются в цикл?). А если внутренние объекты не клонировать, возникает та же проблема: сам объект копируется, а внутренние подобъекты всё равно передадутся по ссылке.

Ответ 2



В отличие от некоторых языков программирования, C # имеет две разновидности типов данных: для значения и для ссылки. Если производительность приложения имеет существенное значение или есть заинтересованность в том, как C# управляет данными и памятью, важно знать различия между этими типами. Если в объявлении переменной используется один из основных встроенных типов данных или определенная пользователем структура данных, значит мы имеем дело с типом значения. Исключение составляет тип данных string, который является ссылочным типом. Структуры и перечисления в C# так же являются значимыми типами(value types). По этому не рекомендуется использовать в качестве аргументов слишком большие структуры, так как это может сказаться на производительности. На счет строк рекомендую прочитать например эту статейку, т.к. со строками не все так очевидно, как могло бы показаться.

Комментариев нет:

Отправить комментарий