none
父類別中的事件,無法在子類別中Raise嗎? RRS feed

  • 問題

  • 我的問題是這樣:我有一個父類別Parent,裡面有個事件OnSomethingHappened,然後我有一個子類別Children繼承Parent,Children裡面有個方法methodA,而methodA方法裡面會Raise這個OnSomethingHappened事件:

    public class Parant {
        protected event SomethingHappened OnSomethingHappened;
        ....
    }

    public class Children : Parent {
        public void methodA() {
            ....
            OnSomethingHappened(string someDesc);
        }
    }

    但是我在建置時收到下面這個錯誤:
        "錯誤    1    事件 'Parent.OnSomethingHappened' 只可以出現在 += 或 -= 左邊"

    請問我該怎麼修正這個錯誤呢? 謝謝!!
    2007年2月7日 上午 10:23

解答

  • 這部份我還沒試過,但你的 delegate 是否為全域委派?
    因為從你提供的程式碼中看不到委派的宣告。

    至於由介面繼承事件是可行的,但 delegate 必須要是全域委派:

    public delegate void TestDelegate();   // delegate declaration
    
    public interface ITestInterface
    {
        event TestDelegate TestEvent;
        void FireAway();
    }
    
    public class TestClass : ITestInterface
    {
        public event TestDelegate TestEvent;
    
        public void FireAway()
        {
            if (TestEvent != null)
            {
                TestEvent();
            }
        }
    }
    
    public class MainClass
    {
        static private void F()
        {
            System.Console.WriteLine("This is called when the event fires.");
        }
    
        static void Main()
        {
            ITestInterface i = new TestClass();
    
            i.TestEvent += new TestDelegate(F);
            i.FireAway();
        }
    }
    
    2007年2月8日 上午 03:27
    版主

所有回覆

  • 我的實作經驗是用抽象類別來做,例如:

        public abstract class DataConverter
        {
            public delegate void ProgressUpdateEventHandler(object sender, ProgressEventArgs e);
            public abstract event ProgressUpdateEventHandler ProgressUpdate;

            public class ProgressEventArgs : EventArgs
            {
                public int maxRows = 0;
                public int currentRowIndex = 0;
            }

            public abstract void DoDataConvert();
            public abstract void GetSourceDataTable();
            public abstract void BuildConvertSqlStatements();
            public abstract Dictionary<int, string> Errors { get; }
        }

    然後子類別要用 override 來繼承這個事件:

        public class UserConverter: DataConverter
        {
            public override event DataConverter.ProgressUpdateEventHandler ProgressUpdate;

            ......

         }

    然後呼叫是用:

                for (int i = 0; i < this._sqlStatements.Count; i++)
                {
                    ProgressEventArgs arg = new ProgressEventArgs();
                    arg.maxRows = this._sqlStatements.Count;

                    try
                    {
                        this._sqlStatementsIdea.Connection = this._destConn;
                        this._sqlStatementsIdea.ExecuteNonQuery();

                        arg.currentRowIndex = i;
                        this.ProgressUpdate(this, arg);
                    }
                    catch (Exception e)
                    {
                        this._errors.Add(i, e.Message + "\r\nCommand:" + this._sqlStatementsIdea.CommandText);
                    }
                }

    2007年2月7日 上午 11:05
    版主
  • 所以是不是說,event 成員是無法直接被子類別繼承呢??
    2007年2月8日 上午 12:17
  • 這部份我還沒試過,但你的 delegate 是否為全域委派?
    因為從你提供的程式碼中看不到委派的宣告。

    至於由介面繼承事件是可行的,但 delegate 必須要是全域委派:

    public delegate void TestDelegate();   // delegate declaration
    
    public interface ITestInterface
    {
        event TestDelegate TestEvent;
        void FireAway();
    }
    
    public class TestClass : ITestInterface
    {
        public event TestDelegate TestEvent;
    
        public void FireAway()
        {
            if (TestEvent != null)
            {
                TestEvent();
            }
        }
    }
    
    public class MainClass
    {
        static private void F()
        {
            System.Console.WriteLine("This is called when the event fires.");
        }
    
        static void Main()
        {
            ITestInterface i = new TestClass();
    
            i.TestEvent += new TestDelegate(F);
            i.FireAway();
        }
    }
    
    2007年2月8日 上午 03:27
    版主