4

我正在使用 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; } }
}    

我想要这个功能的原因主要是为了分离关注点。为了说明,让我们更进一步地模拟汽车。我的车是由很多零件组成的;发动机、轮胎、内饰等。我的轮胎需要每 2 年由轮胎店更换一次。我的发动机需要由机械师每 6 个月更换一次机油。内部需要每 3 个月由装修人员抽真空一次。能够按照以下方式做一些事情会很好

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

这种方法的一些原因;

  • 我想一劳永逸。一旦我安排了我的汽车的一部分进行维修,我希望它能够持续进行,而无需我提供任何进一步的意见。
  • 我不想在我购买新车的那一刻打电话给我的每个服务中心并通知他们。事实上,他们不需要知道我有一辆新车,直到需要维修。如果他们试图维修我的车但它不存在,那么他们可以抛出异常。
  • 我希望我的每项服务都尽可能简单和集中。当轮胎店唯一真正关心的是轮胎时,为什么要让轮胎店参考我的整辆车(包括发动机、内饰等)?
  • 我不希望轮胎店给我一套新轮胎并强迫我自己将它们安装(分配)到汽车上。

我没有接受过任何正规的 CS 教育,我唯一的编程经验是使用 c 和 c# 语言。我刚刚花了 6 个月的时间来熟悉 c# 和 .Net。在大多数情况下,我真的很喜欢这种语言和总体上的早期评估。但是我现在质疑我是否会更好地用一种不同的语言来解决我的特定问题,并内置对惰性评估的支持。

我的问题是;

  1. 如果让我重新开始,解决此类问题的最佳语言是什么?
  2. 是否有任何现有的 c# 平台支持延迟评估?
  3. 在 c# 中进行这项工作的替代方法是什么?我应该阅读任何特定的设计模式吗?
4

2 回答 2

5

听起来您真正想要的是安排稍后重复执行的操作。我建议代表 - 可能使用 lambda 表达式 - 是最合适的方法:

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

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

于 2012-04-18T06:49:45.660 回答
4

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

于 2012-04-18T06:44:00.687 回答