23

バーチャルイベントはどのように機能しますか?どのようにオーバーライドしますか?それはどのように機能しますか?そして、どのような場合にあなたはそれをしますか?

たとえば、保護されたOnEventメソッドの代わりに使用できますか?継承するクラスがイベントをオーバーライドして直接発生させることができるようにするには?それともそれは間違っているのでしょうか、それともうまくいかないのでしょうか?

MSDNはそれについてこれを言います:

virtualキーワードを使用して、イベントを仮想イベントとしてマークできます。これにより、派生クラスは、overrideキーワードを使用してイベントの動作をオーバーライドできます。仮想イベントをオーバーライドするイベントをシールすることもできます。これは、派生クラスの場合、仮想イベントではなくなることを指定します。

しかし、それは私をそれほど賢くしませんでした。しかし、封印されたものは明らかです。

注:C#で仮想イベントがどのように機能するかを見てきましたか?質問ですが、それは実際には仮想イベントがどのように機能するかについてではありませんでした。むしろ、それはその人がそれらを使用することから得た結果をどのようにして得たかでした。彼の例と答えから仮想イベントが何であるかを理解しようとしましたが、それを実際に理解することはできませんでした。

4

3 に答える 3

33

仮想イベントは、派生クラスでオーバーライドできる単純なイベントです。

オーバーライド可能なゲッターとセッターを備えた仮想プロパティの概念に満足していますか? その場合、仮想イベントもまったく同じように考えることができます。ゲッターとセッターの代わりに、「追加」操作と「削除」操作があります。これらは仮想である可能性があるため、ポリモーフィックに処理されます。他の仮想/オーバーライドされたメンバーを実装するのと同じ方法でそれらを実装します。

例:

using System;

class Base
{
    public virtual event EventHandler Foo
    {
        add
        {
            Console.WriteLine("Base Foo.add called");
        }
        remove
        {
            Console.WriteLine("Base Foo.remove called");
        }
    }
}

class Derived : Base
{
    public override event EventHandler Foo
    {
        add
        {
            Console.WriteLine("Derived Foo.add called");
        }
        remove
        {
            Console.WriteLine("Derived Foo.remove called");
        }
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();

        x.Foo += (sender, args) => {};
    }
}

イベント自体は、発生したときに何が起こるかについて責任を負わないことに注意してください。追加/削除側だけです。(とにかく、C# では、CLR 自体にレイズという概念がありますが、当面は無視します。)

イベントとデリゲートの違いが少しわからない場合は、イベントに関する私の記事を読むこともできます。

個人的には、バーチャル イベントを希望することはほとんどありません。

于 2009-07-14T20:38:01.283 に答える
0

また、C#では、派生クラスは基本クラスで純粋に定義されたイベントを発生させることができないことに注意してください(どの修飾子を持っていても)。したがって、派生クラスに対して新しいイベントまたはオーバーライドイベントが必要であり、同じイベントが発生することを意図している場合は、ほとんどの場合、オーバーライドイベントが優先されます。

于 2012-10-08T10:50:05.027 に答える
0

提起されるにはFoo、受け入れられた回答に欠けていると思われる2つの選択肢があります。

public class Base 
{
    public virtual event EventHandler Foo;

    public void Bar()
    {
        RaiseFoo();
    }

    protected virtual void RaiseFoo()
    {
        Foo?.Invoke(this, EventArgs.Empty);
    }
}

public class Derived : Base
{
    // In this case we use the base Foo as a backing store.
    public override event EventHandler Foo
    {
        add { base.Foo += value; }
        remove { base.Foo -= value; }
    }
}

public class Derived2 : Base
{
    public override event EventHandler Foo;

    // In this case we raise the overriden Foo.
    protected override void RaiseFoo()
    {
        Foo?.Invoke(this, EventArgs.Empty);
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.Foo += (sender, e) => { };
        x.Bar();
        Base x2 = new Derived2();
        x2.Foo += (sender, e) => { };
        x2.Bar();
    }
}

これは機能しないことに注意してください。

public class Derived3 : Base
{
    public override event EventHandler Foo
    {
        add { base.Foo += value; }
        remove { base.Foo -= value; }
    }

    protected override void RaiseFoo()
    {
        Foo?.Invoke(this, EventArgs.Empty);
    }
}
于 2019-09-28T21:55:06.760 に答える