C # Автоматическое назначение ссылок - делает ссылки пустыми - PullRequest
1 голос
/ 25 января 2010

Среда сценариев C # в Unity3D (запущена под Mono) хорошо работает при разрушении объектов. Все ссылки, которые указывают на уничтоженный объект, автоматически обнуляются:

    GameObject ref1 = (GameObject)Instantiate(obj);
    GameObject ref2 = ref1;

    if (ref1 != null)
        Debug.Log("ref1 is not null");

    DestroyImmediate(ref1);

    if (ref1 == null)
        Debug.Log("ref1 is null");

    if (ref2 == null)
        Debug.Log("ref2 is null");    

Выход:

    ref1 is not null
    ref1 is null
    ref2 is null

Есть идеи, как этого добиться?

Спасибо

Ответы [ 6 ]

3 голосов
/ 25 января 2010

Может быть, оператор равенства был переопределен? Это объясняет ваш комментарий: «Просто выясните, что если бы ref1 и ref2 были не GameObject, а System.Object, то это не сработало бы».

2 голосов
/ 25 января 2010

Возможно, что Unity3D (ab) использует перегрузку оператора + некоторый вид внутреннего флага, например bool isDeleted;, так что когда isDeleted установлен в true в функции DestroyImmediate, тогда выполняется тест на равенство null дает true.

1 голос
/ 25 января 2010

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

На самом деле в .NET нет полезного понятия о достижимом, но уничтоженном (то есть освобожденном) управляемом объекте (ну, игнорируя WeakReference, который на самом деле не считается). Либо объект недоступен, либо его нельзя уничтожить.

0 голосов
/ 25 января 2010

Вы можете добавить промежуточный класс (прокси), который содержит ссылку на фактический класс.

Все ваши ссылки будут на этот новый GameObjectProxy. Это обеспечит тот же API, что и GameObject, и будет просто перенаправлять любые вызовы на него базовому объекту GameObject.

GameObjectProxy также предлагает дополнительные методы - для уничтожения основного GameObject и запроса, если GameObject имеет значение null. (И они могут быть встроены в operator = и operator ==, если вы хотите быть действительно злым)

Помните, что такой подход может снизить производительность, поскольку каждый вызов GameObject должен перенаправляться через прокси-сервер. Это также в некоторой степени зло - это запутает программистов, которые ожидают, что их ссылки будут вести себя «нормально».

0 голосов
/ 25 января 2010

Хотя это интересная академическая задача, ее не стоит преследовать с технической точки зрения. Вы смотрите на это с неправильной точки зрения - CLR управляет временем жизни объектов для вас. Единственный способ установить все «переменные» в нуль - это передать все переменные с помощью модификатора параметра «ref» в ваш метод destroy. Если вы не планируете писать всю программу внутри одного метода, вы ошибаетесь в дереве. Правильно структурированные классы и методы гарантируют, что переменные, выходящие из области видимости, «обнуляются», освобождая целевой объект для сборки мусора.

0 голосов
/ 25 января 2010

Это невозможно в "обычном" .NET, просто не работает CLR.

...