【发布时间】:2017-11-18 17:12:06
【问题描述】:
有人可以提供一个非常简单的 C# 中自动属性的解释,它们的用途,也许还有一些例子?请尽量保持通俗易懂!
【问题讨论】:
标签: c# .net syntax properties automatic-properties
有人可以提供一个非常简单的 C# 中自动属性的解释,它们的用途,也许还有一些例子?请尽量保持通俗易懂!
【问题讨论】:
标签: c# .net syntax properties automatic-properties
除了上一个答案中提到的方面,我还会注意到自动属性和字段之间的一些差异,因为它们看起来非常相似,并且它们的用法几乎相同:
【讨论】:
编辑:稍微扩展一下,这些用于使类中的私有变量更容易,但允许它们对类外部可见(不能修改它们)
哦,自动属性的另一个优点是您可以在接口中使用它们! (不允许任何类型的成员变量)
使用普通属性,您可以执行以下操作:
private string example;
public string Example
{
get { return example; }
set { example = value; }
}
自动属性允许您创建非常简洁的东西:
public string Example { get; set; }
所以如果你想创建一个只能在类中设置的字段,你可以这样做:
public string Example { get; private set; }
这相当于:
private string example;
public string Example
{
get { return example; }
private set { example = value; }
}
或者在 Java 中:
private String example;
public String getExample() {
return example;
}
private void setExample(String value) {
example = value;
}
编辑:@Paya 还提醒我:
【讨论】:
setExample 为 private 或根本不需要 setter。
许多人已经说过自动属性是语法糖——一种编写简单属性的简写方式。我将处理公共变量和公共属性之间的差异,以及为什么在两者之间切换时需要重新编译。采取以下措施:
public class MyClass
{
public int MyPublicVariable = 0;
public int MyPublicProperty
{
get;
set;
}
}
一旦编译,概念上,它实际上最终类似于以下内容:
public class MyClass
{
public int MyPublicVariable = 0;
private int MyPublicProperty = 0;
public int get_MyPublicProperty()
{
return MyPublicProperty;
}
public void set_MyPublicProperty( int value )
{
MyPublicProperty = value;
}
}
很久以前,属性被发明为一种快速简便的方法来定义成对的 get 和 set 方法。它使代码更易读、更容易理解,因为它们传达了意图并确保了一致性。
MyClass myClass = new MyClass();
myClass.MyPublicVariable = 2;
myClass.MyPublicProperty = 2;
编译后,再次在概念上,它最终类似于以下内容:
MyClass myClass = new MyClass();
myClass.MyPublicVariable = 2;
myClass.set_MyPublicProperty( 2 );
因此,首选公共属性而不是公共变量的原因之一是,如果随着代码的发展需要使用不同的逻辑,那么代码的使用者不一定需要重新编译。这就是为什么它通常被认为是最佳实践。这也是发明自动属性的原因 - 在保持最佳实践的同时加快代码编写速度。
还有一些关于接口的cmets。接口本质上是一种契约,它保证在任何实现它们的类中存在某些方法。从上面我们知道,属性代表一两个方法,所以它们在接口中工作得很好。
希望这会有所帮助。
这是另一个可能感兴趣的例子:
public class MyClass
{
private int[] _myArray = new int[ 5 ];
public int MyArray[ int index ]
{
get
{
return _myArray[ index ];
}
set
{
_myArray[ index ] = value;
}
}
}
public class MyClass
{
private int[] _myArray = new int[ 5 ];
public int get_MyArray( int index )
{
return _myArray[ index ];
}
public void set_MyArray( int index, int value )
{
_myArray[ index ] = value;
}
}
请注意:我记不清反编译时使用的方法签名 特性。我认为是 'get_XXX' 和 'set_XXX' 但它可能是 其他非常相似的东西。只要有理解, 这可能无关紧要。最后,无论如何它们都成为内存地址:-)
【讨论】:
使用以下代码:
using System;
class My Class
{
public string Dummy { get; set; }
public My Class()
{
Dummy = "I'm dummy property";
}
}
class Program
{
static void Main()
{
var my Class = new My Class();
Console .Write Line (my Class .Dummy);
}
}
【讨论】:
如果您问为什么要使用属性或自动属性,这就是它背后的设计理念。
一个重要的设计原则是您从不公开字段,而是始终通过属性访问所有内容。这是因为您永远无法判断何时访问字段,更重要的是何时设置。现在,很多时候,在设置或获取值时不需要任何处理(例如,范围检查)。这就是创建自动属性的原因。它们是一种创建属性的简单的单行方式。它的后备存储由编译器创建。
虽然这甚至是我为内部程序所做的事情,但对于为公众使用(用于销售、开源等)而设计的程序而言,这可能更为重要。如果您使用自动属性,后来又决定需要在 set 或 get 中执行其他操作,则可以轻松更改代码而不会破坏公共接口。
更新
作为对下面评论的澄清点,如果所有代码都是您自己的,那么不,对您来说,属性和字段之间可能没有太大区别。但是,如果您正在设计一个将被其他人使用的库,那么在公共字段和属性之间来回切换将导致异常,除非首先重新编译使用该库的代码。
作为测试,我创建了一个库项目并声明了一个名为TestData 的属性。我创建了一个全新的项目只是为了使用这个库。一切都按预期工作。然后我将该属性更改为公共字段(名称保持不变)并复制新的库 DLL,而无需重新编译使用项目。结果是抛出异常,因为代码期望找到方法属性方法get_TestData 和set_TestData,但字段不是通过方法访问的。
Unhandled Exception: System.MissingMethodException: Method not found: 'Void TestLibrary.TesterClass.set_TestData(System.String)'.
at TestLibraryConsumer.Program.Main(String[] args)
【讨论】:
对于任何 VB.NET 阅读器,其实现方式略有不同。例如:
''' <summary>The property is declared and can be initialized.</summary>
Public Property MyProperty As String = "SomeValue"
但是,关联字段可以通过以下划线前缀显式使用:
Dim sConcat As String = _MyProperty + _MyProperty
_MyProperty = sConcat
在外部代码中:
Dim sMyValue As String = oMyClassObj.MyProperty ' = "SomeValueSomeValue"
就个人而言,我更喜欢这种方法,因为当您使用内部字段或可能暴露的属性时,您可以在使用代码中清楚地看到。
【讨论】:
简化接受的答案,您可以也使用:
public int SomeProperty { get; private set; }
它具有相同的效果,您不再需要为此创建另一个变量。
【讨论】:
public int SomeProperty { get; }(没有private set)设置一个值,就好像您的隐式支持字段被标记为readonly。
当属性访问器中不需要额外的逻辑时,使用自动属性。
声明看起来像这样:
public int SomeProperty { get; set; }
它们只是语法糖,因此您无需编写以下更冗长的代码:
private int _someField;
public int SomeProperty
{
get { return _someField;}
set { _someField = value;}
}
【讨论】:
public int SomeProperty; 这不一样吗?我的意思是,如果这里根本没有私有变量,那我们为什么还需要属性呢?
在早期版本的 C# 中,为了使用属性,您需要创建一个字段来保存值(称为备份存储):
private string _something;
public string Prop { get { return _something; } }
从 C# 3.0 开始,不再需要此要求,编译器会自动为您创建后备存储,因此无需声明 _something 字段。
您可以在此处阅读有关此问题的更多信息:http://msdn.microsoft.com/en-us/library/bb384054.aspx
希望这会有所帮助。
【讨论】:
它们只是为程序员节省几次击键的编码快捷方式。而不是输入所有这些:
private string _lastName;
public string LastName {
get {
return _lastName;
}
set {
_lastName = value;
}
}
你可以输入:
public string LastName {
get; set;
}
并让编译器自动生成其余部分。
【讨论】:
来自Auto-Implemented Properties (C# Programming Guide):
在 C# 3.0 及更高版本中,当属性访问器中不需要额外的逻辑时,自动实现的属性使属性声明更加简洁。它们还使客户端代码能够创建对象。
当您声明一个属性时,编译器会创建一个私有的匿名支持字段,该字段只能通过该属性的 get 和 set 访问器访问。
class Person
{
public string Name { get; set; }
}
【讨论】: