【问题标题】:Use a system class with a different name?使用具有不同名称的系统类?
【发布时间】:2015-09-30 15:59:39
【问题描述】:

我需要一种方法来跟踪网格中的行数和列数。如果我使用 System.Point,我总是会忘记“x”是行数还是列数。所以我有下面的课程。

但我想知道是否有一种方法可以使用 System.Point,并具有不同的命名皮肤?换句话说,我确实想在 System.Point 上定义一个通用的“NRows”或“NColumns”方法。但我确实希望能够返回一个代码将视为“NRowsColumns”对象的对象,但实际上编译为 System.Point。在访问“NRowsColumns”对象时,我们使用字段“NRows”和“NColumns”而不是“x”和“y”。但在后台,它实际上编译为 System.Point。

理想情况下,此定义不限于单个文件。

public class NRowsColumns
{
  public int NRows {get;set;}
  public int NColumns {get;set;}
  public NRowsColumns(int nRows, int nColumns)
  {
    this.NRows = nRows;
    this.NColumns = nColumns;
  }
}

【问题讨论】:

    标签: c# naming renaming


    【解决方案1】:

    不,您不能这样“重命名”成员。如果你真的想要,可以将System.Point 称为NRowsColumns,作为

    using NRowsColumns = System.Point;
    

    ...但它仍将具有与 System.Point 相同的成员。

    通过组合 System.Point 来实现NRowsColumns 会更简单:

    public class NRowsColumns
    {
        private Point point;
    
        public int NRows
        {
            get { ... } // Code using point
            set { ... } // Code using point
        }
    
        ...
    }
    

    话虽如此:

    • 我看不出Point 真的与许多行和列有任何关系。为什么不只有两个整数?
    • 我会在这里重新审视您的命名...N 前缀是非常规的。我可能会称它为GridSizeRowsColumns - 尽管一般来说,即使这似乎没有必要作为单独的类型。 (为什么您的网格本身不通过RowsColumns 属性公开其大小?)

    【讨论】:

    • 关于命名的好建议。如果 OP 想要NumberOfRows,则使用它作为属性名称;否则只需使用RowsNRows 令人困惑。
    【解决方案2】:

    您可以使用conversion operators 来允许您的代码交替使用您的NRowsColumnsPoint

    注意,这不是一个完美的解决方案。来回创建对象具有您应该调查的影响。

    implicit operator 转换添加到您现有的类中:

    public class NRowsColumns
    {
        public int NRows { get; set; }
        public int NColumns { get; set; }
        public NRowsColumns(int nRows, int nColumns)
        {
            this.NRows = nRows;
            this.NColumns = nColumns;
        }
    
        public static implicit operator NRowsColumns(Point p)
        {
            return new NRowsColumns(p.X, p.Y);
        }
    
        public static implicit operator Point(NRowsColumns rowsColumns)
        {
            return new Point(rowsColumns.NRows, rowsColumns.NColumns);
        }
    }
    

    现在你可以来回转换了:

    Point point1 = new Point(5, 10);
    NRowsColumns nRowsColumns = point1;
    Point point2 = nRowsColumns;
    

    请记住,每次“转换”都是一个新对象。

    【讨论】:

      【解决方案3】:

      为什么不直接从 Point 继承?

      public struct  NRowsColumns: Point
      {
         public int NRows {get {return base.x;}}
         public int NColumns {get {return base.y;}}
         public NRowsColumns(int nRows, int nColumns) 
            : base(nRows, nColumns)
         {
         }
      }
      

      【讨论】:

      • 在最好的情况下继承是个坏主意。鼓励以这种肤浅的方式使用它只是一个糟糕的建议。
      • 为什么你认为这是个坏主意?整个 OOP 概念建立在继承(除其他外)之上。我同意它应该用于扩展现有对象的功能,但我认为使用它来提高代码可读性没有任何问题。请赐教。
      • 你可以在simpleprogrammer.com/2010/01/15/inheritance-is-inherently-evil找到一个很好的解释继承的弊端以及为什么接口和组合可以产生更好的代码
      • @DavidArno 你仍然不能说“好吧,我给你 100% 继承是邪恶的,永远不要使用它”。但在这种情况下,我同意你的看法。这不是使用继承的最佳地点,严格来说,在必要时使用它是一个好习惯。
      • @Fabjan,我可以这么说,尽管我接受这是一个可以引领潮流的立场。我完全避免使用gotoswitch 和继承,我的代码更适合它。其他人会及时赶上这个位置。 :)
      猜你喜欢
      • 1970-01-01
      • 2017-02-23
      • 2020-06-27
      • 1970-01-01
      • 2011-11-20
      • 2011-06-01
      • 1970-01-01
      • 2020-04-13
      相关资源
      最近更新 更多