C#中的Setter和Getters如何实现封装?对于这些setter和getter,我不是新手,我有编程背景,特别是java . 在java中你使用像这样的setter和getter
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#速记getter和setter如何实现封装?我如何实现与上面的java代码相同的C#代码?对它有任何限制吗?根据我的观察,我只能使用“fName”,如果它设置为public,特别是“public string fName {get; set;}”,但是当涉及到private时我不能 . 但是当我将它设置为私有时,我无法再以其他方式访问它 .
4 回答
它们不允许您指定封装行为 . 他们所做的是允许您指定这是您的类的公共接口中的属性,而不是字段 .
这里的区别在于,在Java中,getter和setter只是遵循特定约定的方法(getXXX,setXXX) . 在C#中,属性是一流的构造(即使它们基本上是幕后的getter和setter) . 因此,C#提供这些作为一种简写方式,表示您可以稍后实现封装(例如,向getter或setter添加行为),但您不希望破坏类的使用者,因此您可以预先声明它们作为属性 .
在Java中:
在C#中:
让我们假设您在另一个引用Foo程序集的程序集中定义了一个消费者类FooReader:
现在,将Foo更改为此 doesn't break FooReader:
但是改变Foo到这个 WILL break FooReader-你需要重新编译它:
正如您自己所说,C#版本是以下的简写:
(注意私有字段是不可访问的,它是编译器生成的 . 所有访问都将通过属性进行,即使是在类内部)
与java相比,getter / setter只是方法,这个结构在C#中称为属性,是一个编译器特性 .
在,C#中,Person类中的代码相当于:
从C#3开始,您可以将其浓缩为:
这是一个automatically implemented property,编译器将自动生成相同的封装代码,如果您要将其写出来的话 . 将自动为您生成私有支持字段,以及
get
和set
方法 . 真的,一旦编译器生成了IL代码,你将拥有一个包含两个方法的字段,get_Name
和set_Name
,因此通过使用自动实现的属性,你可以让编译器生成几乎与你的代码相同的代码 . 你的java例子 .我将稍微修改您的问题以提供更好的比较 . 在Java中,您通常使用公共getter和私有setter,构造函数是变量的初始值[sic],例如:
该类的用户只能通过构造函数初始化后检索该值:
现在这是C#可能变得混乱的地方,因为您只需使用变量本身而不是使用
Person.getName
,但是这个变量仍然可以被封装 . 在Java中,您会了解到类变量应该是本地的(私有的),并且只能使用getter和setter来访问 . C#本质上是相同的,但语法和逻辑是不同的 . 用C#重写我的例子将是:现在,如果您想使用上述约定向getter和setter添加逻辑,则需要引入一个本地私有变量,但
Example
中的代码和Person构造函数不会更改:现在,这是否比Java更好或更差,这有点值得商榷,但从我所看到的,如果您执行类似下面的操作,您的代码将在C#中不合适,尽管语法方面它将起作用: