如何解决C# 只允许一个类为一个属性调用另一个类的 setter或者让类知道它是否存储在另一个类的数组中
假设我有两个类,例如 Food
和 Barrel
。 Barrel
包含一组食物 private Food[] stores
以跟踪其中存储的内容。 Barrel
还包含访问和修改 stores
的方法,例如 public void Insert(Food)
和 public void Remove(Food)
。
所以 Barrel
可以存储 Food
。但我也希望 Food
知道它的存储位置,如果有的话。例如,我想要一个方法 Food.Rot()
,它只会在没有储存的情况下腐烂食物。
我目前的解决方案是在 public Barrel Container { get; set; }
中有一个属性 Food
来跟踪它存储在其中的 Barrel
实例,并将 Barrel.Insert(Food toAdd)
设置为 toAdd.Container
本身和 Barrel.Remove(Food toRemove)
将 toRemove.Container
设置为 null
(在这种情况下 Food.Rot()
实际上会腐烂食物)。
然而,任何其他类也可以访问 Food.Container
,如果他们写入它,原来的 Barrel
仍然会在 {Food
中拥有这个 stores
实例{1}},但 Food.Container
将不再反映这一点。
我可以让 set 方法确保当 Food.Container
改变时,它首先调用 Container.Remove(this)
,但我真的不希望除了 Barrel
之外的任何东西能够设置 {{1 }} 首先。
我也可以让 Food.Container
根本不存储它的容器,只需让 Food
调用方法 Rot()
来检查每个 bool Isstored()
以查看是否调用它的 Barrel.stores
类的实例存储在内部,这样就没有双向错误,但这对于优化来说似乎很糟糕。
感觉就像我在这个设计的某个地方违反了 OOP,我希望理想情况下需要重新设计整个情况。我也非常愿意接受此类反馈。
解决方法
将食物添加到桶后,您必须修改食物的桶属性。此外,当设置了 Barrel 属性时,如果不存在,您必须将食物添加到 Barrel 中。检查是否存在很重要,否则这两个将相互调用导致 StackOverflow 异常。
您在删除时也必须重复相同的方法。这是您需要的示例:
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute(scoreKey,{action: action}).then(function(token) {
$('#g-recaptcha-response').val(token);
submitForm();
});
});
测试代码:
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));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。