8

最近C#を使い始めましたが、これと同等の方法を見つけたいと思いました。これが何と呼ばれるのかわからないので、コードで簡単に説明します。

Javaを使用すると、次のようなインターフェイスを作成できました。

public interface Event {
    public void execute();
}

そして、このインターフェースを次のようにメソッドのパラメーターに渡します。

public class TestEvent {
    ArrayList<Event> eventList = new ArrayList<Event>();

    public void addEvent(Event event){
        eventList.add(event);
    }

    public void simulateEvent(){
        addEvent(new Event() {
            public void execute(){
                //functionality
            }
        } );
    }

    public void processEvents(){
        for(Event event : eventList)
            eventList.execute();
    }
}

編集:私の質問はsimulatEvent、クラスのメソッドに関連してTestEventおり、そのようなアクションがC#で可能かどうかを示しています。

C#でこれに似た何かをする方法があるかどうか(メソッドのインターフェイスをインスタンス化するsimulateEvent)、そしてこれが実際に何と呼ばれるかを知りたいと思いました。ありがとうございました!

4

2 に答える 2

6

うわー...わかりました、少し一般化させてください:

したがって、Javaでは、関数を渡す方法が必要です。Javaは本質的に第一級市民としての関数をサポートしていません。これが、匿名クラスの実装の背後にある理由の1つです。インラインで宣言し、これらの関数を呼び出すメソッド/他のクラスに(インターフェイスとして)渡すことができる関数のパッケージ化されたグループです。 。

C#では、関数は第一級市民であり、、、、またはのいずれかDelegatesとして宣言できます。(ある種の)比較を試してみましょう:Func<>sAction<>s

ある種のJava-y構造(私のJavaはかなり古いので、我慢してください):

public interface IDoSomething {
    public int Return42();
    public bool AmIPrettyOrNot(string name);
    public void Foo();
} 

public void Main(String[] args) {
    DoStuff(new IDoSomething() {
        public int Return42() { return 42; }
        public bool AmIPrettyOrNot(string name) { return name == "jerkimball"; }
        public bool Foo(int x) { ... }
    });
}

public void DoStuff(IDoSomething something) { ... }

C#でこれに相当する(非常に大まかな)ものは次のとおりです。

public void Main(string[] args)
{
    Func<int> returns42 = () => 42;
    Func<string,bool> amIPretty = name => name == "jerkimball";
    Action<int> foo = x => {};
}

さて、他の人が言及しているように、イベントの処理を処理するとき、通常、Java側でこのパターンが見られます-同様にC#側で:

 public class Foo 
 {
     // define the shape of our event handler
     public delegate void HandlerForBarEvent(object sender, EventArgs args);
     // declare our event
     public event HandlerForBarEvent BarEvent;

     public void CallBar()
     {
         // omitted: check for null or set a default handler
         BarEvent(this, new EventArgs());
     }
 }    

 public void Main(string[] args)
 {
      var foo = new Foo();
      // declare the handler inline using lambda syntax
      foo.BarEvent += (sender, args) => 
      {
           // do something with sender/args
      }
      foo.CallBar();
 }

同じ「形」で何かを与えることもできることに注意してください。

 public void MyHandler(object sender, EventArgs args)
 {
     // do stuff
 }
 public void Main(string[] args)
 {
      var foo = new Foo();
      // that method above is the same "shape" as HandlerForBarEvent
      foo.BarEvent += MyHandler;
      foo.CallBar();
 }

ただし、Javaでは、メモリが機能する場合(つまり)、スレッドが何をするかを定義するためにも使用されますRunnable。これは、C#でも実行できます。

var thread = new Thread((Action)(() => 
     {
         // I'm the threads "run" method!
     });
thread.Start();

さて、他のもの-列挙:

public void processEvents(){
    for(Event event : eventList)
        eventList.execute();
}

C#も同じ考え方で、別の呼び方をしています。

public void processEvents()
{
    // edit: derp, 'event' is a keyword, so I'm
    // renaming this, since I won't get into why
    // you could also use @event...
    foreach(var evt in eventList)
    {
        evt.Execute();
    }
}
于 2013-03-23T00:32:05.753 に答える
2

編集:あなたの質問は、イベントではなく匿名インターフェースの実装に関するもののようです。インターフェイスの代わりに組み込みのActionデリゲートタイプを使用できEventます。

Actionその後、ラムダ式を使用してインスタンス化できます。コードは次のようになります。

public class TestEvent
{
    List<Action> eventList = new List<Action>();

    public void addEvent(Action event){
        eventList.add(event);
    }

    public void simulateEvent(){
        addEvent(() => {
        });
    }

    public void processEvents(){
        for(Action event : eventList)
            event();
    }
}

ie indelegateを使用する代わりに、構文を使用できます。() => { .. .}delegate() { ... }simulateEvent

C#は匿名インターフェースの実装をサポートしていないため、インターフェースに複数のメソッドがある場合は、どこかに具象クラスを定義する必要があります。使用法によっては、このクラスに、作成時に提供できるデリゲートプロパティを含めることができます。

public class Delegates
{
    public Action Event { get; set; }
    public Func<string> GetValue { get; set; }
}

次に、次のように作成できます。

var anon = new Delegates
{
    Event = () => { ... },
    GetValue = () => "Value"
}
于 2013-03-23T00:08:15.650 に答える