161

我想知道这些 getter 和 setter 声明之间有什么区别,以及是否有首选方法(以及为什么)。第一个可以由 Visual Studio 自动生成。其他人呢?谢谢

第一

string _myProperty { get; set; }

第二

string _myProperty;

public string myProperty
{
    get { return _myProperty; }
    set { _myProperty = value; }
}

第三

string _myProperty;

public string getMyProperty()
{
  return this._myProperty;
}

public void setMyProperty(string value)
{
  this._myProperty = value;
}
4

8 回答 8

223

属性用于封装一些数据。您可以使用普通字段:

public string MyField

但是您班级的所有外部用户都可以访问此字段。人们可以插入非法值或以您意想不到的方式更改值。

通过使用属性,您可以封装访问数据的方式。C# 有一个很好的语法可以将字段转换为属性:

string MyProperty { get; set; }

这称为自动实现的属性。当需要时,您可以将您的财产扩展到:

string _myProperty;

public string MyProperty
{
    get { return _myProperty; }
    set { _myProperty = value; }
}

现在您可以添加验证您的值的代码setter

set
{
    if (string.IsNullOrWhiteSpace(value))
        throw new ArgumentNullException();

    _myProperty = value;
}

属性也可以有不同的 getter 和 setter 访问器:

public string MyProperty { get; private set; }

通过这种方式,您可以创建一个所有人都可以读取但只能由类本身修改的属性。

您还可以为您添加一个完全自定义的实现getter

public string MyProperty
{
    get
    {
        return DateTime.Now.Second.ToString();
    }
}

当 C# 编译您的自动实现的属性时,它会生成中间语言 (IL)。在您的 IL 中,您将看到一个get_MyPropertyandset_MyProperty方法。它还创建了一个名为的支持字段<MyProperty>k_BackingField(通常这在 C# 中是一个非法名称,但在 IL 中它是有效的。这样您就不会在生成的类型和您自己的代码之间产生任何冲突)。但是,您应该使用 C# 中的官方属性语法。这在 C# 中创建了更好的体验(例如使用 IntelliSense)。

按照惯例,您不应该将属性用于需要很长时间的操作。

于 2013-07-26T12:30:38.773 回答
15

好吧,第一个和第二个最终都会产生类似于第三个的东西。但是,当您有属性的语法时,不要使用第三个。

get最后,如果你在or中没有工作要做set,那么使用第一个。

最后,第一个和第二个只是某种形式的语法糖,但是为什么代码比必要的要多。

// more code == more bugs

只是为了找点乐子,考虑一下:

public string A { get; private set; }

现在这更直接了,不是吗?public修饰符隐含在和getset,但可以被覆盖。对于定义属性本身时使用的任何修饰符,这当然是相同的规则。

于 2013-07-26T12:19:39.560 回答
12

有了这个,您可以在getorset范围内执行一些代码。

private string _myProperty;
public string myProperty
{
    get { return _myProperty; }
    set { _myProperty = value; }
}

您还可以使用自动属性:

public string myProperty
{
    get;
    set;
}

.Net Framework 将为您管理。之所以创建它,是因为它是一种很好的实践,并且很容易做到。

您还可以控制这些范围的可见性,例如:

public string myProperty
{
    get;
    private set;
}

public string myProperty2
{
    get;
    protected set;
}

public string myProperty3
{
    get; 
}

更新

现在在 C# 中,您可以初始化属性的值。样品:

public int Property { get; set; } = 1;

如果也可以定义它并使其只读,无需设置。

public int Property { get; } = 1;

最后,您可以定义一个箭头函数。

public int Property => GetValue();
于 2013-07-26T12:23:17.417 回答
9

第一

string _myProperty { get; set; }

这在 .NET 世界中称为自动属性。它只是#2 的语法糖。

第二

string _myProperty;

public string myProperty
{
    get { return _myProperty; }
    set { _myProperty = value; }
}

这是执行此操作的常用方法,如果您需要在属性中进行任何验证或额外代码,则需要这样做。例如,在 WPF 中,如果您需要触发属性更改事件。如果你不这样做,只需使用 auto 属性,它几乎是标准的。

3

string _myProperty;

public string getMyProperty()
{
    return this._myProperty;
}

public string setMyProperty(string value)
{
    this._myProperty = value;
}

这里的this关键字是多余的。根本不需要。这些只是获取和设置的方法,而不是属性,就像 Java 做事的方式一样。

于 2013-07-26T12:25:26.060 回答
3

澄清一下,在您的第三个示例中,_myProperty 实际上并不是一个属性。它是一个带有 get 和 set 方法的字段(正如已经提到的,get 和 set 方法应该指定返回类型)。

在 C# 中,在大多数情况下应避免使用第三种方法。如果您想要返回的类型是一个数组,或者如果 get 方法做了很多工作而不仅仅是返回一个值,那么您只会真正使用它。后者并不是真正必要的,但为了清楚起见,执行大量工作的属性 get 方法具有误导性。

于 2013-07-26T13:14:25.277 回答
0

第一个是“短”形式——当你不想用你的 getter 和 setter 做一些花哨的事情时,你可以使用它。不可能以这种形式执行方法或类似的东西。

第二种和第三种形式几乎相同,尽管第二种形式被压缩为一行。stylecop 不鼓励这种形式,因为它看起来有些奇怪并且不符合 C' Stylguides。

如果我希望将我的 getter/setter 用于一些特殊的东西,例如使用惰性构造等,我会使用第三种形式。

于 2013-07-26T12:24:03.967 回答
0

第一个是默认的,当没有什么特别的返回或写入时。2nd 和 3rd 基本相同,其中 3rd 是 2nd 的扩展版本

于 2013-07-26T12:22:28.823 回答
0

让我们从 3 开始。那行不通。public getMyProperty()没有返回类型。

数字 1 和 2 实际上是相同的东西。2 是数字 1 编译后的样子。

所以1和2是一样的。有了两个,您可以在模型中进行一些验证或缓存。

除此之外,它们变得相同。

于 2013-07-26T12:23:13.360 回答