2016-04-17 14 views
3

私が "ヘッドファーストデザインパターン"のコマンドパターンを読んでいる本では、インタフェースをラムダに置き換える例があります。インタフェースを実装しているラムダ

これはJavaだけが可能なものですか?彼らはこれが可能であることを示すいる書籍で enter image description here

// Receiver 
public class Light 
{ 
    public void On() { 
     Console.WriteLine("Lights on"); 
    } 

    public void Off() { 
     Console.WriteLine("Ligts off"); 
    } 
} 

// Command interface 
public interface ICommand 
{ 
    void Execute(); 
} 

// Concrete command 
public class SimpleCommandLightOn : ICommand 
{ 
    private readonly Light light; 

    public SimpleCommandLightOn(Light light) { 
     this.light = light; 
    } 

    public void Execute() { 
     light.On(); 
    } 
} 

// Concrete command 
public class SimpleCommandLightOff : ICommand 
{ 
    private readonly Light light; 

    public SimpleCommandLightOff(Light light) 
    { 
     this.light = light; 
    } 

    public void Execute() 
    { 
     light.Off(); 
    } 
} 

// Invoker 
public class SimpleRemoteControl 
{ 
    private ICommand command; 

    public void SetCommand(ICommand command) { 
     this.command = command; 
    } 

    public void OnButtonPress() { 
     command.Execute(); 
    } 

    // OffCommand needs to be set 
    public void OffButtonPress() { 
     command.Execute(); 
    } 
} 

Light light = new Light(); 
remote.SetCommand(() => light.On()); 

しかし、C#はエラーをスロー は、ここでは例の本から

です。これは、C#で作業する場合はありませんか?

+1

エラーが正確にスローされることを知ることは、むしろ役立つでしょう。 – venerik

+0

C#にはそのような推論はありません。適切な署名の代理人にインターフェイスを置き換える必要があります。 –

+0

C#はサポートしていません。ここに私の[最近の回答](http://stackoverflow.com/a/36137784/2530848)の代替案があります。 –

答えて

5

これは動作しません。C#ではラムダ式がデリゲート(Javaには存在しない概念)にマップされるため、これは機能しません。 Javaには、Java 8でラムダを導入する前に、これらの1メソッド・インタフェースが長い間存在していました。これと、デリゲートの不足を考慮すると、これらの1メソッド・インタフェースをラムダに関連付けるのは多かれ少なかったです。一方、C#/ .NETには、最初から代理人がいて、Javaで1つのメソッドのインターフェイスが見つかる多くの場所で使用されていました。例: ObserverおよびEventHandler

.NET APIでは、ICommandの代わりにActionのようなデリゲートタイプを使用することを検討すると、それにラムダを使用できるようになります。

.NETには1つの方法のインターフェイスもあります。インタフェースまたはデリゲートを選択する際の基本的なガイダンスは、MSDNにあります。

3

マティアス答えは私がちょうどコマンドを宣言するのC#の慣用的な方法は次のようになりますどのように追加してみましょう、素晴らしいです:

delegate void Command(); 

それだこと(最近は、あなただけではなく、一般的なActionデリゲートを使用すると思いますけれども自分自身を定義するよりも)。あなたの方法は

public void SetCommand(Command command) 
{ 
    this.command = command; 
} 

やコマンドを呼び出すだろうSetCommand方法は次のように見ることができるの呼び出し

command(); 

のと同じくらい簡単です:あなたが見ることができるように

SetCommand(() => DoSomething()); // Lambda 
SetCommand(delegate() { DoSomething(); }); // Anonymous method 
SetCommand(Someone.DoSomething); // Named method - Someone can be a type or an instance 

、少しポイントがありますシンプルなデリゲートが行うことができる何かのためのインターフェイスを使用しています。 Javaはデリゲートをサポートしていないため、またC#にはない匿名のインターフェイス実装をサポートしているため、その構文を使用します。

追加のボーナスとして、デリゲートはチェーンをネイティブにサポートしているため、デリゲートはシーケンス内で実行されるデリゲートのセットを表すことができます。これは主にイベントで使用されます。つまり、便利な構文SomeEvent += someDelegate;を使用して、イベントハンドラを登録することで、仕事を少し簡単にする別の構文ヘルパーです。

関連する問題