仅允许从特定类/实例设置属性

时间:2010-06-24 18:42:01

标签: c# wpf design-patterns

想象我有两个A和B类,其中B具有BProperty1和BProperty2属性。

  • 属性BProperty1只能由A类设置(无论哪个实例)
  • 属性BProperty2只能由类A的具体实例设置(对此实例的引用可以例如存储在BProperty1上)。

是否有可能实现类似的东西,是否有可能出现的模式?请注意A和B是独立的,它们都不是来自另一个!我正在使用C#和WPF。谢谢你的提示!

修改 一个例子:

想象一下Car级轿车和CarDoor级轿车。每当将CarDoor添加到Car时,CarDoors属性AssociatedCar将设置为它所分配的Car,因为稍后需要此引用。但是如何确保AssociatedCar属性不是由用户设置的,而是在调用AddCarDoor(门)时由Car类设置的?

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 个答案:

答案 0 :(得分:1)

你可以锁定setter,然后将解锁它所需的对象专用于A类。

编辑:在看到你的编辑之后,我建议你把车门当成班级车的成员,看看汽车是如何由一些x门组成的。或者也许是车门的集合。将该成员变量设为私有。那么汽车类以外的任何东西都无法编辑车门的属性。

Edit2:此外,汽车和轿厢门之间存在双向关联(即轿厢门有相关的汽车,汽车有相关的轿厢门)有点多余。我不明白你为什么需要它 - 只需为车门设置一个公共获取属性,这样你就可以在汽车类之外使用这些数据了。

示例...

Class Car
{
    private List<CarDoor> carDoors;

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

    public List<CarDoor> getCarDoors
    {
         return this.carDoors;
    }
}

答案 1 :(得分:1)

这是一种将责任轻微转移以创建双向依赖的设计:

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。

答案 2 :(得分:1)

您可以将两者放在一个单独的project / assembly / dll中,并在属性集上使用internal关键字。这样,程序集中的任何类都可以更改属性,但由于您可以控制整个属性,因此您可以确保只有Car这样做。

答案 3 :(得分:0)

如果它是属性,您可能希望在属性设置器中使用System.Diagnostics.StackTrace类)。您只需要检查程序集和调用setter的类,如果它是A类以外的类,则抛出异常。

注意:

  • 注意性能问题。
  • 我很确定有人会说,如果你需要做这类事情,那就意味着你的面向对象方法存在缺陷。至少,我曾经使用过这个,我完全同意我的方法是错误的。