Передавая "это" в качестве аргумента - C # - PullRequest
1 голос
/ 18 апреля 2009

В настоящее время я играю с некоторыми вещами XNA, которые учатся программировать AI. В любом случае, вот моя ситуация: у класса A есть функция, которая берет ссылку на экземпляр класса B, делает с ним что-то и возвращает его. Класс B содержит экземпляр класса A, а затем вызывает функцию из него.

Пример в коде:

Class A
{
    B classB;

    public A()
    {
        classB = new B();
    }

    public void Act()
    {
        this = B.Do(ref this);
    }
}

Class B
{
    public A Do(ref A classA)
    {
        //Manipulate
        return classA;
    }
}

Я пытался передать клон для каждого члена ... но это не сработало, очевидно, потому что "this" доступно только для чтения. Я понятия не имею с этим. Я действительно застрял. У кого-нибудь есть идеи? В идеале я бы хотел избежать необходимости передавать каждую переменную в объекте как отдельный аргумент.

Энди.

Ответы [ 8 ]

2 голосов
/ 18 апреля 2009

Классы являются ссылочными типами, поэтому

Class B
{
    public void Do(A classA)
    {
        //Manipulate
    }
}

должен манипулировать ссылками на объект classA. Тогда в A

Class A
{
    B classB;

    public A()
    {
        classB = new B();
    }

    public void Act()
    {
        B.Do(this);
    }
}

Примечание: «У этого есть побочный эффект, что переданная вами ссылка на A не может быть установлена ​​на ноль (будет установлена ​​только локальная переменная на ноль)» - JulianR

1 голос
/ 18 апреля 2009

Ваш метод B.Do () делает это (изменяя A) дважды, используя ref и return. Ни то, ни другое не нужно для изменения класса A. И поскольку вы нацелены на this, это все равно не сработает. Вы никогда не присваиваете this, это не имеет смысла.

Итак, простой ответ -

class B
{
   void Do(A anA) { anA.PublicProp = 1; }
}

Но круговая ссылка делает его сомнительным дизайном.

0 голосов
/ 28 июня 2009

Объекты всегда передаются по ссылке, а не по значению. Вот почему мы называем классы в C # ссылочными типами. Будьте осторожны, если вы используете структуры вместо этого, так как они являются типами значений. Копия структуры будет передана, а не оригинал. Если вы хотите передать оригинал, вы должны добавить ключевое слово ref . ref полезно только для объектов, если вы хотите заменить ссылку на один объект ссылкой на другой объект.

0 голосов
/ 18 апреля 2009

Большое спасибо, Дерек Э!

Я только что проверил то, что вы сказали, и все работало нормально.

Моя проблема, я думаю, в том, что я думал, что когда я передал аргумент, он сделал его клон и манипулировал этим, вместо этого, как (я думаю ..), это делает в PHP или VB (не могу вспомнить, какой из тех, что мне сказали, что это делает в)

0 голосов
/ 18 апреля 2009

Для большей ясности все дело в поведении простого ИИ (например, погоня, охрана, уклонение и т. Д.). Я хочу передать всю сущность AI в поведении, чтобы я мог сохранить поведение отдельно для всех сущностей (вроде как одна таблица стилей для нескольких веб-страниц). Причина, по которой я хочу передать весь объект, заключается в том, что для некоторых видов поведения необходимы определенные части объекта, а для некоторых - нет.

Что касается того, почему я возвращаюсь ... Я не совсем знаю, как я пришел к этому решению. Я удалю это

0 голосов
/ 18 апреля 2009

Вы не можете использовать «ref» с «this». Зачем вам нужен параметр для передачи по ссылке?

Параметр ref нужен только в том случае, если ваша функция должна изменить объект, на который ссылается вызывающий объект. Если все, что вам нужно, это манипулировать и / или изменять поля параметра, то вам не нужен параметр ref.

0 голосов
/ 18 апреля 2009

просто удалите ключевое слово ref. ref нужен только в том случае, если вы хотите изменить аргумент на что-то другое, если вы просто хотите манипулировать им, не используйте ref.

Я думаю, было бы плохо (сложно понять), если бы язык позволил вам изменить это на это, поэтому он запрещает то, что вы пробовали.

0 голосов
/ 18 апреля 2009

Есть ли что-то конкретное в // Манипулировании, которое требует, чтобы вы передавали ссылку на класс как ref? И почему вы также возвращаете classA - это выглядит избыточно, если вы используете ref для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...