【问题标题】:What is the difference between a property and a variable属性和变量有什​​么区别
【发布时间】:2010-11-10 09:20:12
【问题描述】:

我对属性和变量的理解有些困惑

public class ABC()
{
    public int A;
    public int B { get; set; }
}

A 和 B 的具体区别是什么?

【问题讨论】:

标签: c#


【解决方案1】:

正如许多人指出的那样,A 是一个字段,B 是一个属性。

真正的问题是,您为什么要关心,以及使用什么?

我指的是blog post of Jonathan Aneja:

(它在 VB 中,但它也适用于 C#;))

那么为什么要在字段上使用属性,5 个原因:

1。字段不能在接口中使用

你不能强制一个存在 对象的公共合同中的字段 通过一个界面。对于属性 虽然它工作正常。

2。验证

虽然您的申请目前可能 不需要任何验证逻辑 设置一个特定的值,改变 业务需求可能需要 稍后插入此逻辑。那时 点将字段更改为属性 对消费者来说是一个突破性的变化 你的 API。 (例如,如果有人是 通过反射检查你的班级)。

3。二进制序列化

将字段更改为属性是 如果您使用二进制文件,则发生重大变化 序列化。顺便说一句,这是 VB10 的原因之一 自动实现的属性有 “可绑定”支持字段(即您可以 表示支持字段的名称 在代码中)——这样,如果你改变一个 自动实现的属性 扩展属性,你仍然可以 保持序列化兼容性 通过保留支持字段名称 相同(在 C# 中你不得不改变它 因为它会生成支持字段 具有不可绑定的名称)。

4。许多 .NET 数据绑定基础结构绑定到属性而不是字段

我听到了双方的争论 无论这是否是一件好事, 但事实就是这样 现在工作。 (来自我的注意:WPF 绑定适用于属性)

5。公开一个公共字段是一个FxCop violation

出于上面列出的许多原因 :)

可能还有更多原因。

我还想指出 blog post of Jeff Atwood 并引用它作为结尾:

这里真正重要的是要避免编写无关紧要的代码。围绕公共变量的属性包装器是无意义代码的本质。

【讨论】:

【解决方案2】:

A 是一个字段,B 是一个属性。属性基本上是 getter 和 setter 的语法糖。你定义的类会被编译成这样的:

public class ABC()
{
    public int A;

    private int backing_B;

    public void set_B(int value)
    {
        backing_B = value;
    }

    public int get_B()
    {
        return backing_B;
    }
}

请注意,这种转换适用于所有 C# 属性——对 ABC.B 的访问将转换为方法调用。属性基本上提供了“变量”的假象,而实际上只是巧妙伪装的一对方法。

这很重要,因为它允许您声明自己的 get 和 set 方法体,它可以验证值或做其他有趣的事情:

private int b;

public int B {
    get { return b; }
    set {
        if (value < 0) throw new ArgumentOutOfRangeException("value");
        b = value;
    }
}

请注意,大多数属性将使用字段来存储其值。除了字段之外,属性很少单独存在。

【讨论】:

    【解决方案3】:

    在 C# 中,任何具有 getter 和 setter 的“变量”都称为属性。一个变量没有 getter 和 setter,这就是教科书所说的。

    我的编程老师让我们为几乎用 Java 创建的每个变量都设置了 getter 和 setter。即使是在全局类范围内声明的变量,他也让我们使用 getter 和 setter。我认为这可能有点矫枉过正,但它确实让我成为了 getter 和 setter。

    关于 getter 和 setter 的真实情况是,它们很可能不仅仅是设置一个内部变量。大多数 setter 将执行某种类型的数据验证,以确保可以将数据设置为变量。 getter 还可以检查返回的数据是否符合某些条件。

    如果您的属性是私有的,而您的 setter 和 getter 在技术上是公开的,那么任何人都可以访问您的变量并对其进行更改,就好像他们可以公开访问实际变量一样。因此,实际上,您应该检查您的数据以确保其有效或进行其他数据检查。

    private int myVariable;
    public int myVariable 
    {
        get 
        { 
           return myVariable; 
        }
        set 
        {
            if (value < 0) 
            { 
               throw new Exception("This is your exception some where else in code");
            }
            myVariable = value; //remember value is something that is
                                //declared automatically
        }
    }
    
    public string FirstName { get; set; }
    

    上面是下面的简写方式

    private string firstName;
    
    public string FirstName
    {
        get
        {
           //...code here
        }
    
        set
        {
           //...code here
        }
    }
    

    【讨论】:

      【解决方案4】:

      属性是一种简短的 getter 或 setter。您可以将逻辑添加到属性的 set 或 get 或将它们设为私有,这意味着它们无法从外部访问,其中始终可以访问变量(如果它是公共的)。

      【讨论】:

        【解决方案5】:

        变量是一个变量。

        属性是一种公开该变量的特殊方法。由于它是一种方法,因此除了公开变量之外,您还可以在其中做一些其他事情。

        来自 MSDN:

        Property 语句引入了属性的声明。一个属性可以有一个 Get 过程(只读)、一个 Set 过程(只写)或两者(读写)。使用自动实现的属性时,您可以省略 Get 和 Set 过程。有关详细信息,请参阅自动实现的属性 (Visual Basic)。

        您只能在类级别使用属性。这意味着属性的声明上下文必须是类、结构、模块或接口,并且不能是源文件、命名空间、过程或块。有关详细信息,请参阅声明上下文和默认访问级别。

        默认情况下,属性使用公共访问。您可以使用 Property 语句上的访问修饰符来调整属性的访问级别,并且可以选择将其属性过程之一调整为更具限制性的访问级别。

        【讨论】:

          【解决方案6】:

          Microsoft 本身有一篇关于使用字段/变量与属性的非常好的文章(下面的链接)。虽然这篇文章本质上是在讨论 FxCop 违规规则,但它清楚地定义了两者之间的区别以及确切的使用指南。

          文章摘录:

          字段的主要用途应该是作为实现细节。 字段应该是私有的或内部的,并且应该通过使用公开 特性。访问属性就像访问字段一样简单,并且 属性访问器中的代码可以随着类型的特性而改变 在不引入重大更改的情况下扩展。

          参考: https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/ms182141(v=vs.80)

          【讨论】:

            【解决方案7】:

            在您的示例中,A 是 ABC 类的公共字段,B 是 ABC 类的公共属性。具体来说,B 是一个auto-implemented property。这意味着编译器“在后台”为您做了一些工作,并有效地将您的代码转换为:

            public class ABC()
            {
               private int b;
            
               public int A;
               public int B
               {
                   get
                   {
                      return b;
                   }
                   set
                   {
                      b = value;
                   }
               }
            }
            

            【讨论】:

              【解决方案8】:

              变量的定义基本上是为了根据分配给这些变量的修饰符从一个类或同一个类中访问值。

              当我们定义一个属性时,会为单个属性创建两个方法,因此会产生额外的开销,这就是属性的缺点。

              属性的优点是获取或设置类的私有变量的值。

              【讨论】:

                猜你喜欢
                • 2010-10-23
                • 2014-12-12
                • 2016-02-23
                • 2011-02-21
                • 1970-01-01
                • 2012-04-24
                • 1970-01-01
                • 2011-11-14
                相关资源
                最近更新 更多