C # Poster Streamers and Setters

How do Setters and Getters in C # implement encapsulation? I am not a newbie when it comes to these setters and getters; I have programming experience, in particular, 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 the abbreviation

 public class Person { public string fName{ get; set;} } 

How do C # shorthand devices and setters implement encapsulation? How to implement this C # code in the same way as the Java code above? Are there any restrictions regarding this? and based on my observation, I can only use this "fName" if its set is publicly available, namely "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.

+6
source share
4 answers

They do not allow you to specify encapsulating behavior. What they do allows you to indicate that this property is 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 specific convention (getXXX, setXXX). In C # properties, properties are a first-class construct (although they are mostly getters and setters behind the scenes). This way, C # provides them as an abbreviated way of saying that you can later implement encapsulation (e.g. add behavior to getter or setter), but you don't want to break the consumers of your class, so you declare them as properties up.

In Java:

 public class Foo { private String fooName; public String BarName; public String getFooName() { return fooName; } public String setFooName(String fooName) { this.fooName = fooName; } } 

In C #:

 public class Foo { public String FooName { get; set; } public String BarName; } 

Suppose you have a consumer class FooReader defined in another assembly that references the Foo assembly:

 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; } } 

Now, changing Foo to this one does not break FooReader:

 public class Foo { private String _fooName; public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } } public String BarName; } 

but changing Foo to this WILL , break FooReader - you will need to recompile it:

 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; } } } 
+10
source

As you yourself say, the C # version is a shorthand for the following:

 private string _name; public Name { get { return _name; } set { _name = value; } } 

(Note that the private field is not available, its compiler is generated. All your access will be through the property, even from within the class)

Compared to java, where getter / setter are just methods, this construct is called a property in C # and is a compiler.

+4
source

In, C #, the equivalent code inside your Person class will look like this:

 private String _name; public string Name { get { return _name; } set { _name = value; } } 

With C # 3, you can condense this to:

 public string Name { get; set; } 

This is an automatically implemented property , and the compiler will automatically generate the same encapsulating code as it would if you wrote it a long way. A private support field is automatically created for you, as well as get and set methods. Indeed, as soon as the compiler generates IL code, you will have a field with two methods: get_Name and set_Name , therefore, using the automatically implemented property, you enable the compiler to generate almost the same code as you have in your java example.

+2
source

I will modify your question a bit to provide a better comparison. In Java, you usually have public getters and private setters, and the constructor is a parameter of the initialicor [sic] variable, for example:

 public class Person{ private String fName; public Person (String name) { setName(name); } private void setName(String someName){ fName = someName; } String getName(){ return fName; } } 

When the class user can get the value after initialization through the constructor:

 public class Example { Person person = new Person("Fred"); System.out.println(person.getName()); // Allowed System.out.println(person.fName); // Not allowed because fName is a local class variable person.setName("Aaron"); // Not allowed because setName() is a local class method } 

Now, C # can be confused here, because instead of using Person.getName you just use a variable, but this variable can still be encapsulated. In Java, you are taught that class variables must be local (private) and should only be accessible using getters and setters. C # is essentially the same, but the syntax and logic are different. Rewriting my example in C # would be:

 public class Person { public String fName {get; private set;} public Person(String name) { this.fName = name; } } public class Example { Person person = new Person("Fred"); Console.WriteLine(person.fName); // This is allowed person.fName = "Tony"; // Not allowed because setter is private } 

Now, if you want to add logic to your getter and setter using the above conventions, you will need to enter a local private variable, but the code in Example and your Person constructor will not change:

 class Person { private String _fName; public String fName { get { return _fName + ".addedText"; } private set { _fName = value.ToLower(); } } public Person(String fName) { this.fName = fName; } } 

Now whether this is better or worse than Java is somewhat debatable, but from what I saw your code would be inappropriate in C # if you do something like below, although the syntax is wise it will work:

 class Person2 { private String fName; public Person2(string fName) { setFname(fName); } private void setFname(String fName) { this.fName = fName.ToLower(); } public String getFname() { return this.fName+ ".addedText"; } } 
+1
source

Source: https://habr.com/ru/post/906037/


All Articles