iT邦幫忙

0

C# WPF 程式碼優化 (class 繼承 override)

各位前輩好
小弟最近在試著優化C# WPF程式碼,目前遇到一個問題

目前程式有多個Page在主畫面上置換並做各自的事

public partial class PageA : Page
{
    public PageA()
    {
        InitializeComponent();
    }
    
    public void Start()
    {
        // do something
    }
}

public partial class PageB : Page
{
    public PageB()
    {
        InitializeComponent();
    }
    
    public void Start()
    {
        // do something
    }
}
// 類推 PageC、PageD...

用的時候像這樣

public partial class Controller : Window
{
    public Controller()
    {
        InitializeComponent();
        
        pageA = new PageA();
        pageA.Start();
        
        pageB = new PageB();
        pageB.Start();
        
        //...
    }
}

想要把它改成這樣的寫法,比較好維護的感覺

public partial class Controller : Window
{
    public Controller()
    {
        InitializeComponent();
        
        List<Page> pages = new List<Page>();
        pages.Add(new PageA());
        pages.Add(new PageB());
        
        foreach(Page p in pages)
        {
            p.Start();
        }
    }
}

但是Page其實並沒有Start()可以讓我override /images/emoticon/emoticon17.gif
試過自定義一個class去繼承Page,然後再讓PageA那些去繼承

class BasePage : Page
{
    public virtual void Start() { }
}

public partial class PageA : BasePage
{
    public PageA()
    {
        InitializeComponent();
    }
    
    public override void Start()
    {
        // do something
    }
}

但是馬上跳出Error: PageA的部分宣告不得指定不同的基底類別
想試試都不行/images/emoticon/emoticon02.gif

不知道有沒有辦法能在Page加一個Start(),讓我可以去override
還是有更好的做法呢

現在只能暫時用很笨的做法..

PageA pa = (PageA)pages[index];
pa.Start();
fillano iT邦超人 1 級 ‧ 2017-10-30 16:04:35 檢舉
https://social.msdn.microsoft.com/Forums/en-US/829b7620-5066-4ed1-a95e-1ac415b610ec/partial-class-and-inheritance-of-base-class?forum=csharplanguage
椅恩啾 iT邦新手 5 級 ‧ 2017-10-30 17:27:58 檢舉
感謝 fillano 大大分享的網頁,受益良多!
原來partial是這樣的用途

那我出現的Error訊息: PageA的部分宣告不得指定不同的基底類別
是不是因為我嘗試在PageA.xaml.cs檔 使用 partial class PageA : BasePage
然後 PageA.xaml 又使用預設的 <Page x:Class="Project.PageA" >
兩個檔案用了不同的base,加上partial要幫我merge時才出現的error

不知道理解是否有誤

1 個回答

0
dog830228
iT邦研究生 4 級 ‧ 2017-10-30 16:30:50
最佳解答

你可以使用Interface

宣告一個介面 簽章

public interface IPage
{
    void Start();
}

實現IPage

public class PageA : IPage
{
    public void Start()
    {
        Console.WriteLine("PageA");
    }
}

public class PageB : IPage
{
    public void Start()
    {
        Console.WriteLine("PageB");
    }
}

呼叫使用

List<IPage> pageList = new List<IPage>()
{
    new PageA(),
    new PageB()
};
foreach (var item in pageList)
{
    item.Start();
}
看更多先前的回應...收起先前的回應...
椅恩啾 iT邦新手 5 級 ‧ 2017-10-30 17:53:53 檢舉

感謝dog830228大大,使用interface順利解決了我的問題!
但有一個疑問
大大你宣告的是 public class PageA : IPage
這樣把原本的Page拿掉沒有問題嗎?

我實際測試
(A) public class PageA : IPage
(B) public class PageA : Page, IPage
都運行的很順利
但就是不太明白(A)拿掉Page為什麼還可以跑得起來

目前有一個猜測
是不是xaml檔內已有宣告是繼承Page
透過partial,讓xaml檔和xaml.cs檔merge起來
變成 public class PageA : Page, IPage
所以才能順利執行的呢?

dog830228 iT邦研究生 4 級 ‧ 2017-10-30 19:10:46 檢舉

因為我不是使用WPF XD!!

因為C#不支援 多重繼承(最好也不要寫多重繼承)容易出事

上面的例子只是說你可以用介面來做

dog830228 iT邦研究生 4 級 ‧ 2017-10-30 19:34:41 檢舉

PS:我沒寫過WPF 以下的說明是我猜的
椅恩啾 我猜你說得沒錯
在\obj\Debug 資料夾中 可以看到.xaml動態產生程式碼的檔案
在裡面他是使用partial class 並繼承 Page

椅恩啾 iT邦新手 5 級 ‧ 2017-10-31 09:03:59 檢舉

立馬查看了一下\obj\Debug\ 真的有看到partial class!
目前就先當我猜想的沒錯好了/images/emoticon/emoticon37.gif
謝謝!

我要發表回答

立即登入回答