【问题标题】:What's the difference between encapsulating a private member as a property and defining a property without a private member?将私有成员封装为属性和定义没有私有成员的属性有什么区别?
【发布时间】:2011-05-15 02:34:02
【问题描述】:

像这样封装私有成员有什么区别(性能、内存...等)

private int age;
public int Age
{
  get { return age; }
  set { age = value; }
}

并定义这样的属性

public int Age
{
  get ;
  set ;
}

【问题讨论】:

标签: c# performance memory properties


【解决方案1】:

在第二种情况下,C# 编译器将为您生成一个字段并生成一个 getter 和 setter 来访问它。换句话说,您发布的两个代码示例之间没有功能差异。唯一的区别是私有字段的名称,它将由编译器生成。

【讨论】:

  • 差不多就是这个。请注意,您也可以将 setter 设置为私有: public string Name { get;私人套装; }
  • 除非无法创建自动属性readonly,以防止其值在构建后发生变化。仅这一点就阻止了我在许多情况下使用自动属性。
  • @Paul:错了。您可以定义一个自动属性,如public string Foo { get; private set; }。这使得 setter 是私有的,它允许你从你的类内部访问它,但不能从外部访问它。我一直使用这种模式。当然,当您需要执行验证时,自动属性没有用处,但您不能指望每种语言功能都始终有用。
  • @cdhowie:恐怕我没看错。 private set 将访问器设为私有,并且不会阻止从类内对属性进行多次重新分配。 readonly 确保在构造函数完成时填充该字段,并且该字段仅分配一次。
  • @Paul:当然。但是如果你正在编写这个类,那么证明这个作业只发生一次应该是相当容易的。 readonly 在公共领域更有意义,例如EventArgs.Empty
【解决方案2】:

C# 编译器为auto-implemented properties 生成的代码几乎与您的第一个示例相同(它使用私有的支持字段),所以我不会太担心。

唯一真正的区别在于它用[CompilerGenerated] 属性装饰了属性getter 和setter。这不应该对获取和设置属性的性能产生任何影响。 (作为一个小问题,这应该会稍微增加程序集二进制文件的大小)。

我喜欢自动实现的属性,当然,除了简洁之外,它甚至可以防止声明类型访问支持字段而不是属性(支持字段是匿名的)。这使代码更加清晰,并且通常也使重构/更改属性实现更加容易。

【讨论】:

  • 这不是唯一的区别:属性支持字段不能标记为readonly,而显式字段可以。
  • @Paul Ruane:没错,但我说的是OP提供的两个样本之间的差异。
【解决方案3】:

我刚才问了这个问题:

Correct use of C# properties

引用答案:

它们在内部编译形式中是等价的,除了您不能在第二种形式中访问编译器生成的私有变量。

从代码效率的角度来看,它们也是等价的,即时编译器通常直接访问私有变量而无需调用访问函数的开销(在运行时环境检查可访问性等之后) .

从编码的角度来看,我更喜欢第二个版本,它更紧凑(少写,少读)。

第二个语法是在 C# 3.0 中引入的。所以第一个变种会更兼容旧的编译器。

【讨论】:

    【解决方案4】:

    不同之处在于您可以控制 getter 和 setter。

    使用自动实现,您不能执行以下操作:

    private int age;
    
    public int Age
    {
        get { return age; }
        set
        {
            if (age != value)
            {
                age = value;
                OnAgeChanged(EventArgs.Empty);
            }
        }
    }
    
    public event EventHandler AgeChanged;
    
    protected virtual void OnAgeChanged(EventArgs e)
    {
        var handler = AgeChanged;
    
        if (handler != null)
            handler(this, e);
    }
    

    如果你不需要这个,自动实现应该就够了。

    与字段相比,使用自动属性实现的主要优点是,当您使用自动属性实现时,稍后您希望将实现更改为例如以上,你的类的接口没有改变。

    【讨论】:

      【解决方案5】:

      与第二种情况下的性能相比,没有区别是用于编写称为自动属性的属性的合成糖。

      如果你想在 set 或 get part 中放入一些逻辑,你将无法做到自动属性。

      【讨论】:

        猜你喜欢
        • 2018-12-23
        • 2013-02-15
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        • 2010-09-29
        相关资源
        最近更新 更多