有人可以提供有关C#中自动属性的非常简单的解释,它们的用途以及一些示例吗?请尽量保持外行的语言!
Answers:
当属性访问器中不需要其他逻辑时,将使用“自动属性”。
该声明将如下所示:
public int SomeProperty { get; set; }
它们只是语法糖,因此您无需编写以下更冗长的代码:
private int _someField;
public int SomeProperty
{
get { return _someField;}
set { _someField = value;}
}
public int SomeProperty;
?我的意思是,如果这里根本没有私有变量,那为什么我们甚至需要属性?
编辑:稍微扩展一下,这些用于使更容易在类中具有私有变量,但允许它们在类外部可见(而不能修改它们)
哦,自动属性的另一个优点是您可以在接口中使用它们!(不允许任何类型的成员变量)
使用常规属性,您可以执行以下操作:
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。
如果您问为什么要使用“属性”或“自动属性”,这就是其背后的设计原理。
一个重要的设计原则是您从不将字段公开,而是始终通过属性访问所有内容。这是因为您永远无法确定何时访问字段,更重要的是,何时设置字段。现在,很多时候,在设置或获取值时(例如,范围检查)不再需要任何处理。这就是创建自动属性的原因。它们是创建属性的一种简单的单行方法。它的后备存储由编译器创建。
尽管这是我甚至为内部程序所做的工作,但对于那些设计用于公共用途(出售,开放源代码等)的程序而言,这可能更为重要。如果使用自动属性,以后又决定需要在set
或中执行其他操作,则get
可以轻松更改代码而不会破坏公共接口。
更新资料
为了澄清下面的评论,如果所有代码都是您自己的,则否,那么对于您而言,属性和字段之间的差异可能不会太大。但是,如果您设计的库将被其他人使用,则在公共字段和属性之间来回切换会导致异常,除非首先重新编译使用该库的代码。
作为测试,我创建了一个库项目,并声明了一个名为的属性TestData
。我创建了一个新项目来使用该库。一切都按预期工作。然后,我将属性更改为公共字段(名称保持不变),并在新库DLL上进行复制,而无需重新编译使用项目。结果是抛出异常,因为代码希望找到方法的属性methodget_TestData
和set_TestData
,但是不能通过方法访问字段。
Unhandled Exception: System.MissingMethodException: Method not found: 'Void TestLibrary.TesterClass.set_TestData(System.String)'.
at TestLibraryConsumer.Program.Main(String[] args)
在C#3.0和更高版本中,当属性访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁。它们还使客户端代码可以创建对象。
声明属性时,编译器会创建一个私有的匿名后备字段,该字段只能通过属性的get和set访问器进行访问。
class Person
{
public string Name { get; set; }
}
为简化接受的答案,您还可以使用:
public int SomeProperty { get; private set; }
它具有相同的效果,您不再需要为此创建另一个变量。
public int SomeProperty { get; }
(no private set
)设置一个值,就好像您的隐式后备字段已标记一样readonly
。
在C#的早期版本中,为了使用属性,您需要创建一个字段来保存值(称为后备存储):
private string _something;
public string Prop { get { return _something; } }
从C#3.0开始,不再需要此要求,并且编译器将自动为您创建后备存储,因此无需声明_something字段。
您可以在此处阅读有关此问题的更多信息: http //msdn.microsoft.com/zh-cn/library/bb384054.aspx
希望这可以帮助。
许多人已经指出,自动属性是语法糖-一种编写简单属性的简写方式。我将处理公共变量和公共属性之间的区别,以及为什么在两者之间切换时需要重新编译。采取以下措施:
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 );
因此,优先选择公共属性而不是公共变量的原因之一是,如果您需要在代码演化过程中使用不同的逻辑,则代码的使用者不一定需要重新编译。这就是为什么它通常被认为是最佳做法。这也是发明自动属性的原因-可以在保持最佳实践的同时加快代码编写速度。
关于接口也有一些评论。接口本质上是一种契约,它保证在实现它们的任何类中某些方法的存在。从上面我们知道,属性代表一种或两种方法,因此它们在接口中可以正常工作。
希望这有所帮助。
这是另一个可能令人感兴趣的示例:
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”,但可能是其他非常相似的东西。只要有理解,就没什么大不了的。最后,无论如何,它们都成为内存地址:-)
对于任何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"
就我个人而言,我更喜欢这种方法,因为当您使用内部字段或可能公开的属性时,您可以在使用的代码中清楚地看到。
使用以下代码:
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);
}
}