【问题标题】:Should I declare my abstract class's attributes with get; set;?我应该用 get 声明我的抽象类的属性吗?放;?
【发布时间】:2011-01-13 08:08:49
【问题描述】:

我正在制作一个小程序,它将抓取我的硬盘驱动器并显示在给定驱动器中找到的文件列表。

我的想法是有一个基本的File类,并实现从File.cs类继承的Picture.cs、Video.cs和Document.cs类。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpLibrary_MediaManager
{
    public abstract class File
    {
        public string name;
        public string fileType;
        public int size;
        public DateTime creationDate;
        public DateTime modificationDate;        
    }
}

我是否应该像这样声明每个属性的简写代码:

public string name { get; set; }

任何指导都会有所帮助。谢谢你。 :)

编辑:

我的意思是从字面上替换这一行:

public string name;

用这一行:

public string name { get; set; }

【问题讨论】:

标签: c# c#-3.0 properties field


【解决方案1】:

首先,“属性”在这里不是正确的术语。当您声明已定义 get 和/或 set 的类的成员(正式称为“访问器”)时,您正在定义一个属性。属性是公开私有字段值的便捷方式,因为您可以向获取和设置机制添加逻辑。

其次,当你声明一个成员 name 时,你已经通过

public string name { get; set; } 

编译器会将其扩展为以下内容:

private string _name;
public string name {
    get {
        return _name;
    }
    set {
        _name = value;
    }
}

也就是说,编译器会自动为您创建一个支持字段并定义访问器。这些被称为“自动属性”(为人们)1

第三,你不应该2公开公开字段。因此,如果您想将字符串 name 公开为公共接口的一部分,最好将其作为属性进行。首先,它提供了更好的封装。其次,它可以在派生类中声明为虚拟并覆盖。第三,您可以拥有自定义逻辑。第四,属性的读写机制可以有不同级别的可访问性,但字段不能。

第四,根据公认的命名惯例,公共属性应使用CamelCase 命名,因此您应该更喜欢Name 而不是name

1:对不起,我已经等了很久才开的一个糟糕的玩笑。

2:几乎没有。

【讨论】:

  • 是的,我知道。这正是我的问题:抽象类是否应该具有速记类型暴露或只是一个普通的属性声明(没有属性,只有属性)。
  • @Sergio Tapia:您的问题不清楚,因为您错误地使用了术语“属性”。
  • @Sergio Tapia:关于您的编辑,您永远不应该公开公开字段。请看我的第三点。
  • WiFi 的新冒险怎么样? :)
【解决方案2】:

您不是在描述单个项目的简写语法,而是描述两种完全不同类型的成员。 get/set 版本创建一个 C# 属性,而非 get/set 版本创建一个字段。

// field
public string name;  

// property
public string name {get; set;}

因此,您在这里实际上要问的是您是否应该将名称公开为字段或属性。答案几乎肯定是财产。

【讨论】:

    【解决方案3】:

    如果您希望拥有这些属性,即添加 { get; set; } 会生成变量,那么您应该将属性的 set; 部分声明为 protected

    这样就变成了:

    public string name { get; protected set; }

    这样做的好处是您可以保证该属性只能由基类或任何继承该基类的类设置。

    正如其他人所建议的,遵循 C# 命名约定是一个好主意,并且强烈建议使用属性。

    【讨论】:

      【解决方案4】:

      需要明确的是,属性是进行声明式编程的手段。它们用于装饰方法、类等。msdn link

      【讨论】:

        【解决方案5】:

        如果您询问是否公开属性而不是公共字段,那么答案是

        您还应该对属性名称使用 PascalCase 而不是 camelCase:

        public string Name { get; set; }
        public string FileType { get; set; }
        // etc
        

        【讨论】:

        • 不使用速记属性保护字段不被暴露?
        • @Sergio 仅当您应用特定保护级别时,例如:public string FileType { get; internal set; } 将是公共读取,内部写入。
        【解决方案6】:

        正如 Luke 所说,在所有条件相同的情况下,属性优先于字段。

        此外,您可能希望更改字段的大小写以匹配标准 C# naming conventions

        最后,您可能希望避免为您的类使用“File”名称,因为您可能会使用 System.IO 命名空间,该命名空间也有一个 File 类。此外,System.IO.FileInfo 可能已经包含您计划创建的许多属性——重新发明轮子没有意义。

        【讨论】:

          【解决方案7】:

          我相信属性相对于普通公共字段的另一个优势是能够在派生类中覆盖它们。

          class Base
          {
          public virtual int X
          {
          get
          {
          Console.Write("Base GET");
          return 10;
          }
          set
          {
          Console.Write("Base SET");
          }
          }
          }
          
          class Derived : Base
          {
          public override int X
          {
          get
          {
          Console.Write("Derived GET");
          return 10;
          }
          set
          {
          Console.Write("Derived SET");
          }
          }
          }
          

          另一个在使用属性时适用的有用技巧是能够修改派生属性的修饰符,例如从公共访问更改为受保护。

          因此在许多方面最好使用基类中的属性进行派生。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-12-27
            • 1970-01-01
            • 2020-05-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-13
            • 1970-01-01
            相关资源
            最近更新 更多