Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么时候应该对实用程序类使用继承?_C#_Inheritance - Fatal编程技术网

C# 什么时候应该对实用程序类使用继承?

C# 什么时候应该对实用程序类使用继承?,c#,inheritance,C#,Inheritance,我正在从事一个使用Canvas对象的项目。我想添加一些功能来操作它们 直到现在,我还在CanvasUtils类中添加它们,但现在我意识到我实际上可以创建一个CustomCanvas类,该类将继承Canvas并实现新功能 我觉得第二种方法更直观,但我不确定它是否是最好的选择。 例如,如果我一直向CustomCanvas类添加新方法,它在某个时候会变得非常庞大,而我可以轻松地将一个utils类分解为几个类 另外,对我来说,Utils类听起来更为独立和可扩展。例如,如果我想将一些功能扩展到Panel对

我正在从事一个使用
Canvas
对象的项目。我想添加一些功能来操作它们

直到现在,我还在
CanvasUtils
类中添加它们,但现在我意识到我实际上可以创建一个
CustomCanvas
类,该类将继承
Canvas
并实现新功能

我觉得第二种方法更直观,但我不确定它是否是最好的选择。 例如,如果我一直向
CustomCanvas
类添加新方法,它在某个时候会变得非常庞大,而我可以轻松地将一个utils类分解为几个类

另外,对我来说,
Utils
类听起来更为独立和可扩展。例如,如果我想将一些功能扩展到
Panel
对象(
Canvas
继承自
Panel
),我认为使用
Utils
类会更容易,因为您只需将
Canvas
引用更改为
Panel

我的问题是:

  • 每种方法和方法的优点和缺点是什么
  • 什么时候我应该使用一个而不是另一个

  • 如果要添加新功能,则应扩展该类。您将能够添加自己的状态,以及与它们交互的方法。但是,您将无法将此功能添加到现有对象

    如果您只是编写使用现有功能的快捷方式,那么您可以使用添加功能,而无需扩展类。例如

    public static class PanelExtensions    
    {
        public static void DoSomething(this Panel panel) 
        {
            panel.SomePanelMethod();
            panel.SomeOtherPanelMethod();
        }
    }
    
    然后用这个

    Panel myPanel = new Panel();
    myPanel.DoSomething();
    
    这种方法的优点是,这些方法可用于现有面板,并且它们也将被继承(因此您的画布对象也将接收这些方法)


    注意:为了使用扩展方法,您需要在文件顶部有一个
    using
    语句,引用在其中定义它们的命名空间。

    如果要添加新功能,则应该扩展该类。您将能够添加自己的状态,以及与它们交互的方法。但是,您将无法将此功能添加到现有对象

    如果您只是编写使用现有功能的快捷方式,那么您可以使用添加功能,而无需扩展类。例如

    public static class PanelExtensions    
    {
        public static void DoSomething(this Panel panel) 
        {
            panel.SomePanelMethod();
            panel.SomeOtherPanelMethod();
        }
    }
    
    然后用这个

    Panel myPanel = new Panel();
    myPanel.DoSomething();
    
    这种方法的优点是,这些方法可用于现有面板,并且它们也将被继承(因此您的画布对象也将接收这些方法)


    注意:为了使用扩展方法,您需要在文件顶部有一个
    using
    语句,引用在其中定义它们的命名空间。

    如果要添加新功能,则应该扩展该类。您将能够添加自己的状态,以及与它们交互的方法。但是,您将无法将此功能添加到现有对象

    如果您只是编写使用现有功能的快捷方式,那么您可以使用添加功能,而无需扩展类。例如

    public static class PanelExtensions    
    {
        public static void DoSomething(this Panel panel) 
        {
            panel.SomePanelMethod();
            panel.SomeOtherPanelMethod();
        }
    }
    
    然后用这个

    Panel myPanel = new Panel();
    myPanel.DoSomething();
    
    这种方法的优点是,这些方法可用于现有面板,并且它们也将被继承(因此您的画布对象也将接收这些方法)


    注意:为了使用扩展方法,您需要在文件顶部有一个
    using
    语句,引用在其中定义它们的命名空间。

    如果要添加新功能,则应该扩展该类。您将能够添加自己的状态,以及与它们交互的方法。但是,您将无法将此功能添加到现有对象

    如果您只是编写使用现有功能的快捷方式,那么您可以使用添加功能,而无需扩展类。例如

    public static class PanelExtensions    
    {
        public static void DoSomething(this Panel panel) 
        {
            panel.SomePanelMethod();
            panel.SomeOtherPanelMethod();
        }
    }
    
    然后用这个

    Panel myPanel = new Panel();
    myPanel.DoSomething();
    
    这种方法的优点是,这些方法可用于现有面板,并且它们也将被继承(因此您的画布对象也将接收这些方法)


    注意:为了使用扩展方法,您需要在文件顶部有一个
    using
    语句,引用在其中定义扩展方法的命名空间。

    这取决于您试图实现的内容以及实现新功能需要什么:

  • 如果您的无状态方法不需要任何与对象相关的附加信息,那么您可以继续使用Util方法,或者将它们转换为可以给您类似继承的使用感觉和Util类的松耦合:

    public static class CanvasExtensions
    {
        public static void TransformElements(this Canvas canvas,
            Action<CanvasElement> transform)
        {
            ...
            foreach(var elem in canvas.Children)
            {
                transform(elem);
            }
            ...
        }
    }
    
    公共静态类扩展
    {
    公共静态元素(此画布,
    动作转换)
    {
    ...
    foreach(canvas.Children中的变量elem)
    {
    变换(elem);
    }
    ...
    }
    }
    
  • 如果需要将某些信息与操作对象关联,则:

    • 如果对象的行为受到附加功能的深刻影响(如其他标准方法可能否定新功能),则可以继承类,以允许基函数重写:

      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
          }
      }
      
      公共类深度影响画布:画布
      {
      私人字典;
      公共void特殊转换(canvaselem,Action转换){}
      公共覆盖无效调整大小()
      { 
      //例如,调整大小必须考虑
      //特别行动
      }
      }
      
    • 或者创建一个包装器,当附加行为对包装对象影响不大时,该包装器会公开原始对象(面板):

      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(...);
      }
      
      公共类包装器
      {
      公共包装(T包装)
      {
      这个.包裹的=包裹的;
      }
      公共T包装{get;私有集;}
      公共impl