我有一个有三个属性的类:
class PriceCondition
{
public Product SalesCode {...}
public ControlDate Condition {...}
public PriceDetail Pricing {...}
}
PriceCondition
的任何实例只能有SalesCode
或Condition
。如果选择Condition
,则需要Pricing
,但这与此讨论无关。
作为一名相对较差的程序员,我最初尝试过以下方法:
public Product SalesCode
{
get { return _salesCode; }
set
{
this.Condition = null;
_salesCode = value;
}
}
public ControlDate Condition
{
get { return _cond; }
set
{
this.SalesCode = null;
_cond = value;
}
}
事后看来,很明显为什么会造成堆栈溢出。正在寻找正确的方法,我找到this SO answer about XORing a List
,但我无法弄清楚如何将其应用于我正在尝试的内容,因为Except
是一种IEnumerable
方法,并且我没有使用List<T>
或类似的东西。
如何确保任何时候只设置其中一个属性?我可以在构造函数中传递var CodeOrCondition
作为参数,使用typeof
来确定它是什么,然后适当地分配它吗?我只是理解我刚才所说的内容,所以在我开始编写代码之前,先了解一下这是否有用将会有所帮助。
更新
在答案中找到了极好的帮助之后,我最终得到了这个:
public class PriceCondition
{
#region Constructor
/// <summary>Create an empty PriceCondition.
/// </summary>
/// <remarks>An empty constructor is required for EntityFramework.</remarks>
public PriceCondition();
/// <summary>Create a PriceCondition that uses a Sales Code.
/// </summary>
/// <param name="salesCode">The Product to use.</param>
public PriceCondition(Product salesCode)
{
SalesCode = salesCode;
Condition = null;
Pricing = null;
}
/// <summary>Create a PriceCondition that uses a DateControl and Price (e.g. "0D7")
/// </summary>
/// <param name="dateControl">The DateControl Condition to use.</param>
/// <param name="price">The PriceDetail to use.</param>
public PriceCondition(Condition dateControl, PriceDetail price)
{
SalesCode = null;
Condition = dateControl;
Pricing = price;
}
#endregion
....
}
第二次更新:
EntityFramework妨碍了我。我知道它需要空构造函数,但没有意识到原因的深度。我们发现使用private set
可以防止EF从数据库中填充对象。至少那是它的样子。我们在 DBInitializer 中保留了数据,但是当我们尝试使用它时,信息没有加载到PriceCondition
。简单的答案似乎是将设置者放回标准的后备存储方法,并依赖于业务逻辑层,从不在同一SalesCode
上设置ControlDate
和PriceCondition
。但现在这也没有用。我们会更多地抨击它,但任何建议都会非常感激。
答案 0 :(得分:6)
设置支持变量而不是属性:
public Product SalesCode
{
get { return _salesCode; }
set
{
_cond = null;
_salesCode = value;
}
}
public ControlDate Condition
{
get { return _cond; }
set
{
_salesCode = null;
_cond = value;
}
}
我个人喜欢的另一种方法是创建一个不可变对象,并为可能的配置提供构造函数:
class PriceCondition {
public Product SalesCode { get; private set; }
public ControlDate Condition { get; private set; }
public PriceDetail Pricing { get; private set; }
public PriceCondition(Product salesCode) {
SalesCode = salesCode;
Condition = null;
Pricing = null;
}
public PriceCondition(ControlDate condition, PriceDetail pricing) {
SalesCode = null;
Condition = condition;
Pricing = pricing;
}
}
(您还应该验证构造函数中的参数,但这显示了原理。)
答案 1 :(得分:0)
对您的尝试只做一个小改动就可以防止堆栈溢出:
public Product SalesCode
{
get { return _salesCode; }
set
{
<强> 强>
if (value != null)
this.Condition = null;
_salesCode = value;
}
}
答案 2 :(得分:0)
我可以想到这样的事情:
public class PriceCondition
{
private Product m_Product;
private ControlDate m_ControlDate;
public PriceCondition(Product product)
{
m_Product = product;
}
public PriceCondition(ControlDate controlDate)
{
m_ControlDate = controlDate;
}
public Product SalesCode
{
get { return m_product; }
}
public ControlDate Condition
{
get { return m_ControlDate; }
}
}
两个构造函数将始终保证其中一个属性未设置(它实际上为null)。 使用两个只读属性,您始终可以看到设置了哪一个(由于构造函数,将设置其中一个)