C# 只允许一个类为属性调用不同类的 setter(或者让类知道它是否存储在另一个类的数组中)



假设我有两个类,例如FoodBarrelBarrel包含一个食物private Food[] stores数组,用于跟踪其中存储的食物。Barrel还包含访问和修改stores的方法,如public void Insert(Food)public void Remove(Food)

所以Barrel可以存储Food。但我也想让Food知道它存储在哪里,如果有的话。例如,我想要一种方法Food.Rot(),它只会在食物没有储存的情况下腐烂。

我目前的解决方案是在Food中有一个属性public Barrel Container { get; set; },它跟踪存储在其中的Barrel的实例,并让Barrel.Insert(Food toAdd)toAdd.Container设置为自己,Barrel.Remove(Food toRemove)toRemove.Container设置为null(在这种情况下,Food.Rot()实际上会腐烂食物(。

然而,任何其他类也可以访问Food.Container,如果它们向其写入,则原始Barrelstores中仍将具有此Food实例,但Food.Container将不再反映此实例。

我可以让set方法确保当Food.Container更改时,它首先调用Container.Remove(this),但我真的不希望除了Barrel之外的任何东西都能设置Food.Container

我也可以让Food根本不存储它的容器,只需让Rot()调用一个方法bool IsStored()来检查每个Barrel.stores,看看调用它的Food类的实例是否存储在里面,这样就不会有双向的胡言乱语,但这对优化来说似乎很糟糕。

感觉在这个设计的某个地方,我违反了OOP,我希望理想情况下,整个情况需要重新设计。我也非常乐意接受这样的反馈。

食物添加到中时,您必须修改食品木桶属性。此外,当设置了属性时,如果不存在,则必须将食物添加到水桶中。检查是否存在很重要,因为否则,这两者将相互调用以导致StackOverflow异常。

移除时也必须重复相同的方法。这是您需要的样品:

public class Food
{
public string Name { get; set; }
private Barrel _barrel;
public Barrel Barrel
{
get
{
return _barrel;
}
set
{
if (_barrel != null && _barrel != value)
{
_barrel.Remove(this);
}
if (value != null)
{
value.Insert(this);
}
_barrel = value;
}
}
public override string ToString()
{
return Name+"@"+ Barrel??"";
}
}
public class Barrel
{
public string Name { get; set; }
public List<Food> Stores { get; set; } = new List<Food>();
public void Insert(Food food)
{
if (!Stores.Contains(food))
{
Stores.Add(food);
food.Barrel = this;
}
}
public void Remove(Food food)
{
if (Stores.Contains(food))
{
Stores.Remove(food);
food.Barrel = null;
}
}
public override string ToString()
{
return Name;
}
}

测试代码:

Barrel b0 = new Barrel() { Name = "Barrel 0" };
Barrel b1 = new Barrel() { Name = "Barrel 1" };
//Use insert method.
Food fish = new Food() { Name = "Fish" };
//I will insert fish to b0 first.
b0.Insert(fish);
b1.Insert(fish);
//Assign barrel directly
Food chicken = new Food() { Barrel = b0, Name = "Chicken" };
//then change barrel
chicken.Barrel = b1;
Debug.WriteLine("Barrel 1:"+ string.Join(",",b1.Stores));
//Modify Barrel attribute
chicken.Barrel = null;
Debug.WriteLine("Barrel 1:" + string.Join(",", b1.Stores));
//Remove from stores
b1.Remove(fish);
Debug.WriteLine("Barrel 1:" + string.Join(",", b1.Stores));

输出:

Barrel 1:Fish@Barrel 1,Chicken@Barrel 1
Barrel 1:Fish@Barrel 1
Barrel 1:

相关内容

  • 没有找到相关文章

最新更新