关于c#:Public accessor .net


Public accessor .net

我想是在.NET 2.0中,微软引入了一个访问器,它被缩写为

public string Name { get; set; }

但是,上述代码之间是否存在真正的区别,并且简单地说:

1
public string Name;


主要的区别在于,如果您以后需要向getter或setter中添加逻辑,并且其他dll已经针对您的dll进行了编译,那么您可以轻松地更改

1
public string Name { get; set; }

进入之内

1
public string Name { get{/*special code*/} set{/*special code*/} }

而且发布新的DLL和不重新编译其他DLL不会是一个破坏性的更改。

但是如果你改变了

1
public string Name;

进入之内

1
public string Name { get{/*special code*/} set{/*special code*/} }

然后,您需要确保重新编译使用您的DLL,因为它们从访问字段变为访问属性。

这显然是一个更大的问题,当你把DLL发送给其他程序员(例如,作为一个开源项目或组件供应商)时,比你只是为自己的自己/雇主构建一个应用程序时


C 3.0首次引入了自动特性。区别在于:

1
public string Name { get; set; }

1
public string Name;

第一个声明属性,第二个声明字段。在OOP中,属性用于封装字段。属性可以有一个setter或一个getter或两者都有,您还可以为每个属性指定不同的可访问性级别。


区别在于字段和属性之间。字段只是类实例上的成员变量。相比之下,属性是两个独立操作的简写形式-get和set:

1
2
3
4
5
6
7
8
9
10
11
12
13
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

private string _name;

这是一个过于简化的示例,因为属性只是通过在getter中返回私有字段并在setter中设置它来"包装"私有字段。但是,当属性成为基础值的"网关"时,它们变得非常有用。如果程序流要求每次设置字段值时都发生某些事情(例如,激发事件),则可以从属性的setter激发该事件:

1
2
3
4
5
set
{
    this.InvokePropertyChangedEvent();
    _name = value;
}

您所询问的确切语法称为自动实现的属性,这只是我上面提供的简单示例的简写。编译器创建由属性获取和设置的私有成员。


只要编写代码来获取值或存储值,就没有功能上的区别。但在某些情况下,调用者可能期望一个字段或属性,并且只使用反射接受其中一个或另一个字段或属性。例如,WPF只能绑定到属性,而不能绑定到字段。


速记属性声明之间的区别在于您可以这样定义它。

1
public string Name { get; private set; }

这意味着属性可以公开读取,但只有私有成员才能写入其中。你不能为一块地做这种事。

If you look at the generated IL of
short-hand property declarations, you
will find that the compiler has added
/ autogenerated member-fields to a
property will read from or write into.


是的,第二行中的代码可以直接使用内存中的成员,而第一行中有一个间接级别,您可以在将来添加一些逻辑来验证和延迟分配。

此外,如果使用反射,则必须查找第一个示例行的属性setter和getter,第二个示例行需要直接检索成员变量。

通常,使用属性是更好的设计。


对于PropertyGrid用户,我发现一个有用的区别是公共字符串名称get;set;我们可以轻松地在PropertyGrid中设置源数据。

声明时公共字符串名称;将不完全用于PropertyGrid。