2015-03-31 53 views
0

我正在研究一個使用Canvas對象的項目。我想添加一些功能來操作它們。什麼時候應該通過實用程序類使用繼承?

到現在爲止,我在CanvasUtils類中添加了它們,但現在我意識到我實際上可以創建一個CustomCanvas類,它將繼承Canvas並實現新的功能。

我能感覺到第二種方式更直觀,但我不確定它是否是最佳選擇。例如,如果我不斷向類添加新方法,它在某些時候會變得很大,而我可以輕鬆地將一個utils類分成幾個類。

另外一個Utils類聽起來更獨立,可擴展給我。例如,如果我想將某些功能擴展到Panel對象(Canvas繼承自Panel),我認爲使用Utils類更容易,因爲您只需將Canvas引用更改爲Panel即可。

我的問題是:

  1. 什麼優勢和每種方法的缺陷和
  2. 我應該使用一個比另一個?
+1

總是很難談論設計。有人知道這一點 - 在很多情況下 - 通過* trail-and-error * ... – 2015-03-31 09:39:48

+0

我意識到這一點。但是如果你可以利用別人的經驗,那就比不斷重新發明自己的輪子要好。 :) – user3240131 2015-03-31 13:17:07

回答

2

如果您要添加新功能,則應該擴展該類。您可以添加自己的狀態,以及與它們交互的方法。但是,您將無法將此功能添加到現有對象。

如果您只是編寫使用現有功能的快捷方式,那麼您可以使用Extension Methods添加功能而無需擴展該類。例如...

public static class PanelExtensions  
{ 
    public static void DoSomething(this Panel panel) 
    { 
     panel.SomePanelMethod(); 
     panel.SomeOtherPanelMethod(); 
    } 
} 

然後使用這個......

Panel myPanel = new Panel(); 
myPanel.DoSomething(); 

這種方法的優點是方法可用於現有的面板,它們也會被繼承(所以你的Canvas對象也會收到這些方法)。

注意,爲了使用擴展方法,您需要在文件頂部有一個using語句引用它們所在的命名空間。

+1

這個例子並不合理。爲什麼使用'myPanel.DoSomething()'而不是'myPanel.SomePanelMethod()'更好?擴展方法實際上是爲了避免在C#中缺少多個實現繼承。 – 2015-03-31 09:41:05

+1

@GáborAngyal*擴展方法實際上是爲了規避C#中多重實現繼承的缺失*不正確;擴展方法被添加來支持'Linq';這與多繼承無關。你在談論的是接口的工作。 – 2015-03-31 09:56:44

+0

在這個例子中,我正在做一件事,是的沒有意義。但是考慮一下當你可能經常爲面板做10件事時,那麼它就更有意義。 – Richard 2015-03-31 09:57:08

1

這取決於你需要實現新的功能,你想實現什麼和什麼:

  1. 如果不需要與對象相關聯的任何其他信息,然後您可以無狀態的方法繼續使用的Util方法或把它們變成Extension methods,這將使你都使用的繼承般的感覺和的Util類的鬆耦合:

    public static class CanvasExtensions 
    { 
        public static void TransformElements(this Canvas canvas, 
         Action<CanvasElement> transform) 
        { 
         ... 
         foreach(var elem in canvas.Children) 
         { 
          transform(elem); 
         } 
         ... 
        } 
    } 
    
  2. 如果你需要一些片INF的關聯Ø你要操作的對象,則:

    • 你可以繼承類,如果對象的行爲應被深深打動了額外的功能(比如當其他標準方法可以否定新功能),以允許基函數重載:

      public class DeeplyAffectedCanvas : Canvas 
      { 
          private IDictionary<CanvasElement, Action> m_dictionary; 
      
          public void SpecialTransform(CanvasElement elem, Action transform) { } 
      
          public override void Resize() 
          { 
           // Resize, for example, have to take into account 
           // the special operation 
          } 
      } 
      
    • 或創建一個包裝,暴露原始對象(面板)當附加行爲不影響被包裝對象得多:

      public class Wrapper<T> 
      { 
          public Wrapper(T wrapped) 
          { 
           this.Wrapped = wrapped; 
          } 
      
          public T Wrapped { get; private set; } 
      
          public implicit operator T (Wrapper<T> wrapper) 
          { 
           return wrapper.Wrapped; 
          } 
      } 
      
      public class WrappedCanvas : Wrapper<Canvas> 
      { 
          private Object data; 
          public void SafeTransform(...); 
      } 
      
相關問題