Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.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# getter和setter的主要区别是什么?_C# - Fatal编程技术网

C# getter和setter的主要区别是什么?

C# getter和setter的主要区别是什么?,c#,C#,我知道这可能是个愚蠢的问题。我参考了一些文章。但是,我很想知道以下代码的主要区别 using System; namespace Business { public class User { private int _id; public int ID { get { return _id; } set { _id = value; } } } } 及 我

我知道这可能是个愚蠢的问题。我参考了一些文章。但是,我很想知道以下代码的主要区别

using System;

namespace Business
{
    public class User
    {
        private int _id;

        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }
    }
}

我想知道一些简要的细节(任何参考资料)


谢谢

编译完成后,它们是一样的

public int ID { get; set; }
只是“语法糖”

这被称为“”,如果您有如示例中所示的“空getter/setter”,那么它对于减少锅炉板代码非常有用

使用auto属性,您不能再直接访问backing字段,因为它只在编译之后存在,如果getter/setter没有被JIT内联,这可能会导致非常小的性能缺陷

此外,目前还无法直接初始化自动属性,但在即将推出的C#6中,您可以执行以下操作:

public int ID { get; set; } = 0;

自动实现的属性()
是在C#3.0中引入的,在此之前,您必须使用第一个版本。

编译器没有任何区别,但代码有区别

您没有办法在auto属性上截取
set
get
,这在正常情况下是可以做到的。如果你曾经使用过WPF,你会发现“正常”属性被大量使用

public int Data  {
    get {}  
    set {
       //Do something ehere
    }
}

这意味着您不能调试它们(自动属性)或将断点放在其中。

在您的示例中没有区别

然而,封装是面向对象编程的一个重要方面。您通常不希望有一个完全开放的setter

namespace Business
{
    public class User
    {
        private int _id;

        public int ID
        {
            get { return _id; }
            set { 
              if (value <= 0) 
                   throw new ArgumentOutOfRangeException(value, "value", "Impossible value");

              _id = value; }
        }
    }
}

引入了自动实现的属性以促进和简化这一过程:

private int _id;

public int ID
{
    get { return _id; }
    set { _id = value; }
}
为此:

public int ID { get; set; }
从编译器的角度来看,这两段代码是相同的

但是,如果您想在属性中引入任何逻辑,那么自动实现的属性就不是一条出路

例如,如果要验证提供的
id
值必须始终为非负值,则可以在setter内部实现如下逻辑:

private int _id;

public int ID
{
    get
    {
        return _id;
    }
    set
    {
        if (value < 0)
        {
            throw new BusinessException("You must provide a non-negative number for ID.");
        }

        _id = value;
    }
}
private int\u id;
公共整数ID
{
得到
{
返回_id;
}
设置
{
如果(值<0)
{
抛出新的BusinessException(“您必须为ID提供一个非负数”);
}
_id=值;
}
}

使用自动实现的属性无法实现这种灵活性。

在表面下,第二个示例与第一个示例类似,但在构造函数中,您也可以设置自动属性,因此,它的优点是什么?好处是,您可以在不使用构造函数的情况下设置支持字段。实际上,您可以将断点放入自动实现的属性中,但这是一个PITA:
Debug
->
新断点
->
在函数处中断
并输入
您的类名。将您的属性名称
放入
函数
文本框中。
public int Data  {
    get {}  
    set {
       //Do something ehere
    }
}
private int _id;

public int ID
{
    get
    {
        return _id;
    }
    set
    {
        if (value < 0)
        {
            throw new BusinessException("You must provide a non-negative number for ID.");
        }

        _id = value;
    }
}