Чи передаються масиви або списки за замовчуванням за посиланням у c #?


84

Вони? Або щоб пришвидшити мою програму, чи повинен я передавати їх за посиланням?


35
Щоб пришвидшити програму, вам слід (1) встановити значущі цілі, (2) перевірити, чи досягли ви своїх цілей, (3) якщо цього не зробили, скористайтеся інструментом профілювання, щоб знайти найповільніше, і (4 ) оптимізувати найповільніше.
Ерік Ліпперт,

1
Дивіться це також stackoverflow.com/q/4311226/344822
Прабхакаран

3
@EricLippert Ваш коментар відповідає на справжнє запитання OP набагато краще, ніж будь-яка з опублікованих відповідей. Усі були настільки відволікані на технічні характеристики "передачі посилань за значенням", що повністю пропустили реальне питання про оптимізацію продуктивності. На жаль, ОП повідомив про його потреби досить погано, а інші відповіді принаймні допоможуть натовпу Google.
Ден Бешард

"інші відповіді принаймні допоможуть натовпу Google" - вони допоможуть! :)
miki

Відповіді:


208

Посилання передається за значенням .

Масиви в .NET є об'єктом у купі, тому у вас є посилання. Це посилання передається за значенням, тобто зміна вмісту масиву буде видно абоненту, але перепризначення масиву не буде:

void Foo(int[] data) {
    data[0] = 1; // caller sees this
}
void Bar(int[] data) {
    data = new int[20]; // but not this
}

Якщо ви додасте refмодифікатор, посилання передається посиланням - і абонент побачить будь-яку зміну вище.


28
Відповідь правильна, але я ненавиджу домашніх тварин до людей, які заявляють, що "посилання передається за значенням". Це бентежить питання. Так, посилання (адреси пам'яті) передаються за значенням, але це не було питання.
WernerVA,

9
@WernerVA Мені цікаво, як ти думаєш, що ти висловив би це по-іншому, що залишається правильним і однозначним
Марк Гравелл

2
Я б не висловлював інакше, просто, можливо, трохи детальніше.
WernerVA

Це не відповідає на питання швидкості. Вам, мабуть, очевидно, що оптимізація еталонної копії буде абсолютно незначною у порівнянні з сотнями інших набагато дорожчих операцій, що відбуваються, але ОП запитував це конкретно.
Ден Бешард

7
@Dan частина швидкості за своєю суттю пов'язана з "якщо масив передається за значенням - це означає копію вмісту масиву - це означає виділення та копію всієї пам'яті". Оскільки це посилання, яке передається, відповіді на запитання щодо продуктивності немає - ця частина запитання стає спорною і відповідає автоматично. За винятком зараз, тут також явно відповідають у коментарях ...
Марк Гравелл

9

Вони передаються за значенням (як і всі параметри, які не є ані ref, ані ззовні), але значення є посиланням на об'єкт, тому вони ефективно передаються за посиланням.


0

Так, вони передаються за посиланням за замовчуванням у C #. Усі об'єкти в C # є, крім типів значень. Якщо бути трохи точнішими, вони передаються "за посиланням за значенням"; тобто значення змінної, яке ви бачите у своїх методах, є посиланням на переданий вихідний об'єкт. Це невеликий смисловий момент, але той, що іноді може бути важливим.


9
Посилання передається за значенням; що дуже відрізняється від "вони передаються за посиланням".
Марк Гравелл

1
Це прямо протилежне істині. Цитуючи цю публікацію від Джона Скіта : "За замовчуванням усі параметри передаються за значенням у C #. Параметри передаються лише за посиланням, якщо ви явно включаєте модифікатор out або ref. Однак ви повинні знати, що коли тип параметра є типом посилання, ви передаєте посилання, а не фактичний об'єкт ". Це лише посилання (адреса пам'яті), яке передається за значенням.
alexlomba87
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.