Совместное использование ссылки между объектами - PullRequest
3 голосов
/ 08 июля 2010

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

class SomeObject
{
    private ref DataObject _data;
    public SomeObject(ref DataObject data)
    {
         _data = ref data; // or something similar
    }

    public ChangeData(DataObject newData)
    {
         _data = data;
         // at this point, *other* SomeObject instances that were
         // created with the same reference should also have _data == newData
    }
}

Но, конечно, вы не можете использовать ref таким образом: ref только для параметров метода.И статическое поле не будет работать, так как не все SomeObject экземпляры должны ссылаться на один и тот же объект - скорее, рассматриваемый объект должен быть установлен в конструкторе.

Очевидно, я мог бы решить эту проблему, просто добавив простой класс-обертку.Но есть ли лучший способ?Есть ли какой-нибудь класс SharedReference<T>, который я могу использовать?

Обновление , так как большинство ответов неправильно поняли то, что я спрашивал.Я знаю, что поле _data содержит ссылку на исходный DataObject.То, что я хочу, это еще один уровень косвенности.Я хочу иметь возможность изменить объект, на который я указываю в одном экземпляре, и получить новое значение для других экземпляров, созданных с той же ссылкой.Как показывает обновленный пример кода, я хочу присвоить _data и эффективно изменить значение _data в других случаях.

Ответы [ 4 ]

4 голосов
/ 08 июля 2010

Я не знаю ни одного класса, который вы могли бы использовать для этого, но мне кажется, довольно легко реализовать свой собственный класс SharedReference<T>.

Примерно так:

public sealed class SharedReference<T>
    where T : class
{
    public T Reference
    {
        get; set;
    }
}
1 голос
/ 08 июля 2010

Вы можете просто использовать массив общих объектов и переназначить элементы массива:

class SomeObject
{
    // you probably want to make this readonly
    private readonly DataObject[] _data;     

    public SomeObject(DataObject[] data)
    {
         _data = data;
    }

    public void ChangeData(DataObject newData)
    {
        _data[0] = o;
    }

    // and you could define your own accessor property...
    private DataObject Data
    {
        get { return _data[0]; }
        set { _data[0] = value; }
    }
}

Кроме того, я думаю, вам нужно определить свой собственный класс 'держатель' и использовать этот

1 голос
/ 08 июля 2010

Если вы просто предоставите ссылку на объект без ключевого слова ref, вы получите желаемое поведение.Использование ref фактически передает ссылку на ссылку (указатель на указатель), поэтому, если вы не хотите null чужую ссылку, она не будет вам полезна.

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

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

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

0 голосов
/ 08 июля 2010

В C #

<del>
class SomeObject
{
    private DataObject _data;
    public SomeObject(DataObject data)
    {
         _data = data;
    }
}
</del>

фактически делает именно то, что вы хотите, если DataObject является ссылочным типом, который имеет значение для всех классов.

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

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