user962206 user962206 - 4 months ago 15
Java Question

The C# Shorthand getters and setters

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.

Answer

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:

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

Lets assume 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 doesn't 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'll 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; } }
}