【发布时间】:2011-09-27 12:37:15
【问题描述】:
我的问题是基于this article。
基本上一个类可以实现一个 Freezable 方法来确保一旦对象进入 Frozen 状态就不能更改任何属性。
我有一个遵循这个设计的界面
public interface IFreezableModel
{
void Freeze();
bool IsFrozen{get;}
}
目标是确保一旦调用 Freeze 方法,IsFrozen 属性设置为 True 并且对象的属性不能再更改。
为了简化,我将使用抽象基类:
public abstract class BaseFreezableModel : IFreezableModel
{
public void Freeze()
{
_isFrozen = true;
}
public bool IsFrozen
{
get {return _isFrozen;}
}
protected ThrowIfFrozen()
{
if (IsFrozen)
throw new Exception("Attempted to change a property of a frozen model");
}
}
这样我就可以上课了
public class MyModel : BaseFreezableModel
{
private string _myProperty;
public string MyProperty
{
get{return _myProperty;}
set
{
ThrowIfFrozen();
_myProperty = value;
}
}
}
这一切都很好而且很简单,但是我可以采用哪种策略来确保所有属性都遵循上述模式? (除了写 setter 和 getter)
这些是我想出的替代方案:
找到一种机制,或许可以使用 emit 将方法注入每个属性设置器。但我不知道该怎么做,我可能会遇到哪些潜在问题(以及需要多长时间)。如果有人知道这一点并能指出我的方向,那就太好了。
在构建过程中使用一些模板,以便在编译时间之前插入对 OnCheckFrozen 的调用。这具有非常易于理解并且可以用于类似场景的优点。
找到一个可以为我完成所有这些工作的框架,但这只是一个极端情况,因为我不允许在这个项目上使用外部框架。
您会使用什么解决方案来完成此任务?
【问题讨论】:
-
我看不出这个类是如何线程安全的:冻结状态与其他线程不同步。
-
@Luca Piccioni 它们只是我能想到的最简单的例子。但是,一旦类被冻结,它将是线程安全的(文章中显示的少数情况)
-
我们有不同的线程安全概念。链接的文章明确地说:只读结构不是线程安全的。如果您这样做是为了线程安全,我建议您更改设计。我的 2 美分。
-
@LucaPiccioni 是的,我已经阅读了这篇文章。我还重新阅读了我写的问题,我很确定我没有提到任何关于线程安全的内容。这篇文章还有一个非常具体的标题:“只读和线程安全是不同的” 我很确定我也没有错过。当然,我可以重新表述我之前提到的内容:对于最简单的情况(值类型属性、不可变对象),一旦对象被冻结,我可以假设它是线程安全的。
-
就个人而言,我会将
OnCheckFrozen更改为ThrowIfFrozen。