C#速记getter和setter
C#中的Setter和Getters如何实现封装? 对于这些设置者和获取者,我并不陌生,我有编程背景,特别是java。 在Java中,你使用setter和getters这样的
public class Person {
private String fName;
public void setName(String someName) {
fName = someName;
}
public String getName() {
return fName;
}
}
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.setName("Bob");
System.out.println(p.getName());
}
}
并在C#中使用速记
public class Person {
public string fName{ get; set;}
}
C#简写获取器和设置器如何在此上实现封装? 我如何实现与上面的java代码相同的C#代码? 有关于它的限制吗? 根据我的观察,我只能使用那个“fName”,如果它设置为public,特别是“public string fName {get; set;}”,但是当涉及到私有我不能。 但是当我将它设置为私人时,我无法再通过其他方法访问它。
他们不允许你指定封装行为。 他们所做的是允许你指定这是你的类的公共接口中的一个属性,而不是一个字段。
这里的区别在于,在Java中,getter和setter只是遵循某种约定的方法(getXXX,setXXX)。 在C#中,属性是一流的构造(即使它们基本上是幕后的获取者和设置者)。 因此,C#提供了这些作为一种简短的方式来表示你可能稍后实现封装(例如向getter或setter添加行为),但不希望打破你的类的消费者,所以你先声明它们为属性。
在Java中:
public class Foo {
private String fooName;
public String BarName;
public String getFooName() { return fooName; }
public String setFooName(String fooName) { this.fooName = fooName; }
}
在C#中:
public class Foo {
public String FooName { get; set; }
public String BarName;
}
让我们假设你在另一个引用Foo程序集的程序集中定义了一个消费者类FooReader:
public class FooReader {
public String ReadFoo(Foo foo) {
// This returns the Foo **property**
return foo.FooName;
}
public String ReadBar(Foo foo) {
// This returns the Bar **field**
return foo.BarName;
}
}
现在,将Foo更改为此不会中断FooReader:
public class Foo {
private String _fooName;
public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } }
public String BarName;
}
但将Foo更改为此将会打破FooReader,您需要重新编译它:
public class Foo {
private String _fooName;
private String _barName;
public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } }
// This breaks FooReader because you changed a field to a property
public String BarName { get { return _barName.ToUpper(); } set { _barName = value; } }
}
正如你所说,C#版本是以下的简写:
private string _name;
public Name
{
get { return _name; }
set { _name = value; }
}
(请注意,私人领域是不可访问的,它是编译器生成的。所有的访问都将通过属性,即使在类中也是如此)
与java比较,getter / setter只是方法,这个构造在C#中被称为属性,并且是一个编译器特性。
在C#中,Person类中的代码相当于:
private String _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
从C#3开始,您可以将其简化为:
public string Name { get; set; }
这是一个自动实现的属性,编译器会自动生成相同的封装代码,因为如果要长时间写出它的话。 自动生成一个专用的后台字段,以及get
和set
方法。 真的,一旦编译器生成了IL代码,你将得到的是一个有两个方法的字段, get_Name
和set_Name
,所以通过使用自动实现的属性,你让编译器生成几乎相同的代码你的java例子。