c#的后期评估?

时间:2012-04-18 06:41:36

标签: c# programming-languages lazy-evaluation

我正在使用c#中的应用程序。为了使这个应用程序工作,我发现自己做了一些对我选择的语言感到非常不自然的事情。在经历了许多重构和改进后,我逐渐意识到我试图实现的功能实际上是一种“懒惰评估”(我认为)。这就是我想要的......

// Criteria 1: Lazy evaluation of expressions
int x = LazyEvaluated.New<int>();
int y = LazyEvaluated.New<int>();
int z = LazyEvaluated.New<int>();

z.Assign(x + y);
Assert.ThrowsException(z.Evalutate());
x.Assign(1);
Assert.ThrowsException(z.Evalutate());
y.Assign(2);
Assert.Equals(3, z.Evaluate());
x.Assign(3);
Assert.Equals(5, z.Evaluate());

// Criteria 2: Referencing relative to parent object    
Car myCar = LazyEvaluated.New<Car>();
Engine engineInMyCar = LazyEvaluated.New<Engine>();
double displacementOfMyEngine = LazyEvaluated.New<double>();

engineInMyCar = myCar.Engine;
displacementOfMyEngine = engineInMyCar.Displacement;

Car subaru = new Car(new FlatFourEngine());
Car falcon = new Car(new InlineSixEngine());

myCar.Assign(subaru);
Assert.IsTypeOf<FlatFourEngine>(engineInMyCar.Evaluate());
Assert.IsEqual(2.0, displacementOfMyEngine.Evaluate());

myCar.Assign(falcon);
Assert.IsTypeOf<InlineSixEngine>(engineInMyCar.Evaluate());
Assert.IsEqual(4.0, displacementOfMyEngine.Evaluate());

这些是我用于说明的简单类定义......

public class Car {
    private readonly Engine engine;            
    public Car(Engine engine) { this.engine = engine; }
    public Engine Engine { get { return engine; } }
}

public abstract class Engine {
    public abstract double Displacement { get; }
}        

public class FlatFourEngine : Engine {
    public override double Displacement { get { return 2.0; } }
}

public class InlineSixEngine : Engine {
    public override double Displacement { get { return 4.0; } }
}    

我想要这个功能的原因主要是为了分离关注点。为了说明,让我们进一步采用汽车模拟。我的车由很多东西组成;发动机,轮胎,内饰等。我的轮胎需要每两年更换一次轮胎车间。我的发动机需要每6个月由机修工换油一次。内部需要由细节设备每3个月抽真空一次。能够按照......的方式做一些事情会很好。

tyreShop.ReplaceTyres(myCar.Tyres, every2Years);
mechanic.ChangeOil(myCar.Engine, every6Months);
detailer.VacuumInterior(myCar.Interior, every3Months);

这种方法的一些原因;

  • 我想忘了。一旦我计划将我的汽车的一部分用于服务,我希望它能够在没有任何进一步输入的情况下持续发生。
  • 我不想打电话给我的每个服务中心,并在我购买新车时立即通知他们。事实上,他们不需要知道我有一辆新车,直到有时间提供服务。如果他们试图维修我的车并且它不存在,那么他们可以抛出异常。
  • 我希望我的每项服务都尽可能简单和专注。为什么让轮胎车间参考我的整辆车(包括发动机,内饰等),他们真正唯一关心的是轮胎?
  • 我不希望tyreshop给我一套新的轮胎并强迫我自己将它们分配给汽车。

我没有CS的正规教育,我唯一的编程经验是c&amp; c#语言。我刚刚在过去的6个月里熟悉了c#&amp; 。净。在大多数情况下,我非常喜欢语言和早期评估。但我现在正在质疑我是否会更好地用另一种语言解决我的特定问题,内置支持懒惰评估。

我的问题是;

  1. 如果我重新开始,解决这个问题的最佳语言是什么?
  2. 是否有任何现有的c#平台为懒惰评估提供支持?
  3. 使用c#进行此项工作的替代方法是什么?我应该阅读哪些特定的设计模式?

2 个答案:

答案 0 :(得分:5)

在安排稍后重复发生的操作之后,这听起来像是 。我建议委托 - 可能使用lambda表达式 - 是最合适的方法:

scheduler.Schedule(every3Months, () => tyreShop.ReplaceTyres(myCar));

这样,您需要了解懒惰方面的唯一代码就是调度程序本身。您的所有其他代码都可以假设,当您调用方法时,您希望立即执行该操作,这更像是惯用的C#。

答案 1 :(得分:4)

.NET 4内置了对使用Lazy进行延迟初始化的支持,请参阅MSDN上的文档。 http://msdn.microsoft.com/en-us/library/dd642331.aspx