Почему использование 'касательно' ключевого слова при передаче объекта?

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

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

268
задан Jim Fell 27 May 2016 в 07:09
поделиться

9 ответов

Передайте ref, если Вы хотите изменить, каков объект:

TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(ref t);

void DoSomething(ref TestRef t)
{
  t = new TestRef();
  t.Something = "Not just a changed t, but a completely different TestRef object";
}

После вызова DoSomething, t не обращается к оригиналу new TestRef, но относится к совершенно другому объекту.

Это может быть полезно также, если Вы хотите изменить значение неизменного объекта, например, string. Вы не можете изменить значение string, как только оно было создано. Но при помощи ref, Вы могли создать функцию, которая меняет струну для другого, который имеет различное значение.

Редактирование: Поскольку другие люди упомянули. Это не хорошая идея использовать ref, если это не необходимо. Используя ref дает свободу метода изменить аргумент в пользу чего-то еще, вызывающие стороны метода должны будут быть кодированы, чтобы гарантировать, чтобы они обработали эту возможность.

кроме того, когда тип параметра является объектом, затем переменные объекта всегда действуют как ссылки на объект. Это означает, что, когда ref ключевое слово используется, у Вас есть ссылка на ссылку. Это позволяет Вам делать вещи, как описано в примере, данном выше. Но, когда тип параметра является примитивным значением (например, int), тогда если этому параметру присвоят в рамках метода, то значение аргумента, который был передан в, будет изменено после возвратов метода:

int x = 1;
Change(ref x);
Debug.Assert(x == 5);
WillNotChange(x);
Debug.Assert(x == 5); // Note: x doesn't become 10

void Change(ref int x)
{
  x = 5;
}

void WillNotChange(int x)
{
  x = 10;
}
281
ответ дан cp.engr 23 November 2019 в 02:22
поделиться

Необходимо различать "передачу ссылки значением", и "передачу параметра/аргумента ссылкой".

я написал довольно длинная статья о предмете , чтобы избежать необходимости писать тщательно каждый раз, когда это подходит на группах новостей:)

87
ответ дан Malice 23 November 2019 в 02:22
поделиться

В.NET при передаче любого параметра методу создается копия. В значении типы означают, что любая модификация, которую Вы делаете к значению, в объеме метода и потеряна при выходе из метода.

При передаче Ссылочного типа, копия также сделана, но это - копия ссылки, т.е. теперь у Вас есть ДВЕ ссылки в памяти к тому же объекту. Так, при использовании ссылки для изменения объекта, она изменяется. Но если Вы изменяете саму ссылку - мы должны помнить, что это - копия - тогда, любые изменения также потеряны после выхода из метода.

, Поскольку люди сказали прежде, присвоение является модификацией ссылки, таким образом потерян:

public void Method1(object obj) {   
 obj = new Object(); 
}

public void Method2(object obj) {  
 obj = _privateObject; 
}

методы выше не делают изменяет исходный объект.

Немного модификации Вашего примера

 using System;

    class Program
        {
            static void Main(string[] args)
            {
                TestRef t = new TestRef();
                t.Something = "Foo";

                DoSomething(t);
                Console.WriteLine(t.Something);

            }

            static public void DoSomething(TestRef t)
            {
                t = new TestRef();
                t.Something = "Bar";
            }
        }



    public class TestRef
    {
    private string s;
        public string Something 
        { 
            get {return s;} 
            set { s = value; }
        }
    }
51
ответ дан dipdapdop 23 November 2019 в 02:22
поделиться

Так как TestRef является классом (которые являются ссылочными объектами), можно изменить содержание внутри t, не передавая его как касательно Однако при передаче t как касательно TestRef может изменить то, к чему относится оригинал t. т.е. заставьте его указать на различный объект.

17
ответ дан Ferruccio 23 November 2019 в 02:22
поделиться

С ref можно записать:

static public void DoSomething(ref TestRef t)
{
    t = new TestRef();
}

И t будет изменен после того, как метод завершился.

15
ответ дан Peter Mortensen 23 November 2019 в 02:22
поделиться

Это похоже на передачу указателя на указатель в C. В.NET это позволит Вам изменять то, что оригинал T отсылает к, лично , хотя я думаю, делаете ли Вы это в.NET, Вы, вероятно, получили вопросы проектирования!

5
ответ дан pezi_pink_squirrel 23 November 2019 в 02:22
поделиться

При помощи ref ключевое слово со ссылочными типами Вы эффективно передаете ссылку на ссылку. Во многих отношениях это совпадает с использованием out ключевое слово, но с незначительными различиями, что нет никакой гарантии, что метод на самом деле присвоит что-либо ref 'параметр редактора.

3
ответ дан Isak Savo 23 November 2019 в 02:22
поделиться

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

1
ответ дан Andrew 23 November 2019 в 02:22
поделиться

Касательно обозначает, может ли функция достать сам объект, или только его значение.

Передача ссылкой не связывается с языком; это - стратегия привязки параметров рядом с передачей значением, передачей по имени, передачей потребностью и т.д.

заметка на полях А: имя класса TestRef является ужасно плохим выбором в этом контексте;).

1
ответ дан xtofl 23 November 2019 в 02:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: