C# 速记 getter 和 setter
C#中的Setter和Getter是如何实现封装的?我对这些 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 string fName{ get; set;}”,但当涉及到私有时,我不能。但是当我将其设置为私有时,我无法再通过其他方法访问它。
How does the Setters and Getters in C# implement Encapsulation? I am not new when it comes to these setters and getters, I have background with programming, specifically java. in java you use setters and getters like this
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());
}
}
And in C# Using Shorthand
public class Person {
public string fName{ get; set;}
}
How does the C# shorthand getters and setters implement encapsulation on this? how do I implement that C# code the same as the java code above? are there any restrictions regarding it? and base from my observation, I can only use that "fName" if its set to public, specifically "public string fName{ get; set;}" but when it comes to private I cannot. but when i set it to private, I can no longer access it in other methods.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它们不允许您指定封装行为。它们的作用是允许您指定这是类的公共接口中的属性,而不是字段。
这里的区别在于,在 Java 中,getter 和 setter 只是遵循特定约定(getXXX、setXXX)的方法。在 C# 中,属性是一流的构造(尽管它们基本上是幕后的 getter 和 setter)。因此,C# 提供这些作为一种简写方式,表示您可能稍后实现封装(例如,向 getter 或 setter 添加行为),但您不想破坏类的使用者,因此您需要预先将它们声明为属性。
在 Java 中:
在 C# 中:
假设您在另一个引用 Foo 程序集的程序集中定义了一个消费者类 FooReader:
现在,将 Foo 更改为此 不会 破坏 FooReader:
但将 Foo 更改为此 将会破坏 FooReader - 你需要重新编译它:
They don't allow you to specify encapsulating behavior. What they do is allow you to specify that this is a Property in the public interface of your class, as opposed to a field.
The difference here is that in Java, getters and setters are simply methods that follow a certain convention (getXXX, setXXX). In C#, properties are a first-class construct (even though they are basically getters and setters behind the scenes). So C# provides these as a shorthand way of saying you might implement encapsulation later (e.g. add behavior to the getter or setter) but you don't want to break consumers of your class, so you are declaring them as properties up front.
In Java:
In C#:
Lets assume you have a consumer class FooReader defined in another assembly that references the Foo assembly:
Now, changing Foo to this doesn't break FooReader:
but changing Foo to this WILL break FooReader- you'll need to recompile it:
正如您自己所说,C# 版本是以下内容的简写:(
请注意,私有字段不可访问,它是编译器生成的。您的所有访问都将通过属性进行,甚至是从类内部进行)
与 java 相比,其中 getter/setter 是简单的方法,此构造在 C# 中称为属性,并且是编译器功能。
As you say yourself, the C# version is a shorthand for the following:
(Note that the private field isn't accessable, it's compiler generated. All your access will be via the property, even from inside the class)
In comparision to java, where getter/setter are simply methods, this construct is called a property in C#, and is a compiler feature.
在 C# 中,Person 类中的代码等效于:
从 C# 3 开始,您可以将其压缩为:
这是一个 自动实现的属性,编译器将自动生成与您长时间编写的封装代码相同的封装代码。系统会自动为您生成私有支持字段以及
get
和set
方法。实际上,一旦编译器生成 IL 代码,您将拥有一个包含两个方法的字段:get_Name
和set_Name
,因此通过使用自动实现的属性,您可以让编译器生成与 java 示例中几乎相同的代码。In, C# the equivalent of the code inside your Person class would be:
As of C# 3, you can condense that down to:
This is an automatically implemented property and the compiler will automatically generate the same encapsulating code as it will if you were to write it out the long way. A private backing field is automatically generated for you, as well as the
get
andset
methods. Really, once the compiler generates the IL code, what you'll have is a field with two methods,get_Name
andset_Name
, so by using the auto-implemented property, you're letting the compiler generate nearly the same code as you have in your java example.我将稍微修改你的问题以提供更好的比较。在 Java 中,通常有公共 getter 和私有 setter,构造函数是变量的初始化器[原文如此],例如:
类的用户只能在通过构造函数初始化后检索值:
现在这就是C# 可能会变得令人困惑,因为您只需使用变量本身,而不是使用
Person.getName
,但是该变量仍然可以被封装。在 Java 中,您被告知类变量应该是本地(私有)的,并且只能通过 getter 和 setter 来访问。 C#本质上是一样的,只是语法和逻辑不同。用 C# 重写我的示例将是:现在,如果您想使用上述约定向 getter 和 setter 添加逻辑,则需要引入一个本地私有变量,但是
Example
中的代码和您的 Person构造函数不会改变:现在这是否比 Java 更好或更差还有些争议,但从我所见,如果你执行如下所示的操作,你的代码将在 C# 中不合适,尽管从语法角度来看,它会工作:
I'm going to modify your question slightly to provide a better comparison. In Java you commonly have public getters and private setters, with the constructor being the initializor[sic] of the variable, such as:
With a user of the class only being able to retrieve the value after initialization through the constructor:
Now this is where C# can become confusing, as instead of using
Person.getName
you simply use the variable itself, however this variable can still be encapsulated. In Java you are taught that Class variables should be local (private) and should only be accessed with getters and setters. C# is essentially the same, but the syntax and logic is different. Rewriting my example in C# would be:Now if you wanted to add logic to your getter and setter using the above conventions, you would need to introduce a local private variable, but the code in
Example
and your Person constructor wouldn't change:Now whether this is better or worse than Java is somewhat debatable, but from what I've seen your code is going to be out of place in C# if you do something like the below, although syntax wise it will work: