Разрешить установку свойства только из определенного класса / экземпляра - PullRequest
3 голосов
/ 24 июня 2010

представьте, у меня есть два класса A и B, где B имеет свойства BProperty1 и BProperty2.

  • Свойство BProperty1 должно устанавливаться только классом A (независимо от того, какой экземпляр)
  • Свойство BProperty2 должно устанавливаться только конкретным экземпляром класса A (ссылка на этот экземпляр может быть, например, сохранена в BProperty1).

Возможно ли реализовать нечто подобное, может быть, есть шаблон для этого? Обратите внимание, что A и B независимы, ни один из них не является производным от другого! Я использую C # и WPF. Спасибо за любую подсказку!

EDIT Пример:

Представьте себе класс Car и класс CarDoor. Каждый раз, когда CarDoor добавляется в Car, свойству CarDoors AssociatedCar присваивается значение Car, которому он назначен, поскольку эта ссылка понадобится позже. Но как убедиться, что свойство AssociatedCar задается не пользователем, а классом Car при вызове AddCarDoor (door)?

class Car
{
    private List<CarDoor> _carDoors = new List<CarDoor>();

    public Car()
    {

    }

    public void AddCarDoor(CarDoor door)
    {
        // Add the door to the car
        _carDoors.Add(door);

        // Save a reference to the car assigned to the door
        door.AssociatedCar = this;
    }
}


class CarDoor
{
    public Car AssociatedCar;

    public CarDoor()
    {

    }
}

Ответы [ 4 ]

1 голос
/ 22 декабря 2010

Вы можете поместить их вместе в отдельный проект / сборка / dll и использовать ключевое слово internal в наборе свойств. Таким образом, любой класс внутри сборки может изменить свойство, но так как вы контролируете все это, вы можете убедиться, что только Car делает это.

1 голос
/ 24 июня 2010

Вы можете заблокировать установщик, а затем сделать объект, необходимый для разблокировки, закрытым для класса А.

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

Edit2: Кроме того, имеется двусторонняя связь между автомобилем и дверью автомобиля (т. Е. С дверью автомобиля связан автомобиль и автомобиль).имеет связанные автомобильные двери) немного избыточно.Я не понимаю, зачем вам это нужно - просто установите публичное свойство get для автомобильной двери, чтобы вы могли использовать эти данные вне класса автомобиля.

Пример ...

Class Car
{
    private List<CarDoor> carDoors;

    Car()
    {
         this.carDoors = new List<CarDoor>();
    }

    public List<CarDoor> getCarDoors
    {
         return this.carDoors;
    }
}
1 голос
/ 24 июня 2010

Вот один дизайн, который слегка меняет обязанности для создания двусторонней зависимости:

class CarFactory
{
    public Car BuildCar()
    {
        return new Car(BuildDoor);
    }

    public CarDoor BuildDoor(Car car)
    {
        return new CarDoor(car);
    }
}

class Car
{
    private List<CarDoor> _carDoors = new List<CarDoor>();

    public Car(Func<Car, CarDoor> buildDoor)
    {
        for (int i=0; i<4; i++)
            _carDoors.Add(buildDoor(this));
    }
}


class CarDoor
{
    private Car _associatedCar;

    public CarDoor(Car associatedCar)
    {
        _associatedCar = associatedCar;
    }
}

Обратите внимание, что такая двусторонняя зависимость является признаком других проблем. Может быть, CarDoor делает то, что не должно нести за это ответственность. Возможно, Car должен заниматься этими вещами, или, возможно, вы включили обязанности, которые действительно принадлежат другому классу, например, Mechanic.

0 голосов
/ 24 июня 2010

Если это свойство, вы можете использовать System.Diagnostics.StackTrace class) внутри установщика свойства.Вам просто нужно проверить сборку и класс, который вызвал установщик, и сгенерировать исключение, если это класс, отличный от класса A.

Примечания:

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