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

あなたが本当に求めているのは、後で繰り返し実行するアクションをスケジュールしているようです。これには、デリゲート(おそらくラムダ式を使用)が最も適切なアプローチであることをお勧めします。

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

このように、怠惰の側面について知る必要があるコードの唯一の部分は、スケジューラー自体です。コードの残りのすべては、メソッドを呼び出すときに、そのアクションを今すぐ実行することを想定できます。これは、はるかに慣用的なC#です。

于 2012-04-18T06:49:45.660 に答える
4

Lazy.NET 4には、MSDNのドキュメントを参照し てレイジー初期化のサポートが組み込まれています。http://msdn.microsoft.com/en-us/library/dd642331.aspx

于 2012-04-18T06:44:00.687 に答える