I am trying to understand the difference between the C# auto declaration of variables with getters & setters & the java declaration.
In java I usually do this:
private int test;
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
But in C# I tried something like this:
private int test { public get; public set};
But that did not allow access to the variable at all.
So I ended up with this:
public int test { get; set; }
So this way I could access the variable test from outside of the class.
My question is, what is the difference between these two? And is the C# implementation of making the variable public a bad idea?
In C# I have declared the variable as "public". Whereas in java it is declared as "private". Does this have any impact?
Found a really good answer (in addition to those below) here
It is exactly the same.
The automatic property you defined in C# will compile down to getter and setter methods anyway. They are classified as "syntactic sugar".
This:
public int Test { get; set; }
..is compiled to this:
private int <>k____BackingFieldWithRandomName;
public int get_Test() {
return <>k____BackingFieldWithRandomName;
}
public void set_Test(int value) {
<>k____BackingFieldWithRandomName = value;
}
In the first example you have a backing field.
In C# You can do:
private int test { get; set; };
Or make the property public (Perfectly valid)
public int test { get; set; };
You can also have backing fields in C#, these were more common before Properties were introduced in the language.
For instance:
private int _number = 0;
public int test
{
get { return _number; }
set { _number = value; }
}
In the above example, test is a public Property that accesses a private field.
Here is the solution, which is provided by the C# compiler to eaisly create getter and setter method.
private int test;
public int Test{
public get{
return this.test;
}
public set{
this.test = value;
}
}
Related
For proper encapsulation, should I use a private property with a manual getter method like in Java:
public class Foo {
private int Prop { get; set; }
public Foo
{
Prop = 1;
}
public int GetProp()
{
return Prop;
}
}
Or should I simply use a public property?
public class Foo {
public int Prop { get; private set; }
public Foo
{
Prop = 1;
}
}
Properties are the way of creating getters and setters in C#, so there is no reason to create a getter method, like you would in Java.
In other words: You should use the second example.
Typically the proper way to do this is:
private int prop;
public int Prop
{
get { return prop; }
set { prop = value; } //do other stuff within set if needed.
}
This way you have access to everything, but can still do something custom (commonly NotifyPropertyChanged) if needed.
A property is just a syntactic sugar for get_PropertyName and set_PropertyName methods in c#.
public class Foo
{
public int Prop { get; private set; }
}
Is equivalent to:
public class Foo
{
private int _prop;
private void set_prop(int value) { _prop = value; }
public int get_prop() { return _prop; }
}
It's best that you use auto properties when possible and use properties with backing fields when you need to add logic to the getter/setter of individual fields.
If the property is going to be private, as it is in your first example, you should just use a field.
The point of a Property is usually that you have a get and set function, that can be used mostly like a variable. Your first example is really wierd - why not just make the getter only public? Readonly and Writeonly properties are not a uncommon sight:
//Public property with private get or writeonly
public int Prop { private get; set; }
//Readonyl property
public int Prop { get; private set; }
One important rule regarding the Backing field: It is very important that you do not mix up the Property and it's backing field, especially in class code. If you use Autoimplement Properties, that danger is non-existant. If your code is more complex than that, a common approach is to append a underscore (_) to the backing field name. Prop/prop is too easy to mix up. _Prop and Prop are really hard to mix up ,especialyl for autocompletion features.
In general, methods represent actions and properties represent data. While both your examples can be used identically, the 'proper' way of representing state is through properties, and using properties correctly tells consumers of your object that this is representing state, not an action.
You should also consider how things like serialization and intellisense are expecting properties instead of methods.
For example if we have class MyClass with private field. Is it possible to set value via class object.
public class MyClass { private int field; }
public class Program
{
public static void Main()
{
MyClass cl = new MyClass();
cl = 10; // set value
}
}
It's not directly possible like that in C#, but it's possible to do it through implicit operator overloading by instantiating the class from a value.
public class MyClass
{
private int field;
public static implicit operator MyClass(int value)
{
return new MyClass { field = value };
}
}
Which you can then use like:
MyClass myClass = 100;
That's the closest you will get to what you want.
Other than that you can really only do it through constructors or reflection.
No. But you can expose a method that set the value.
private int _field;
public void SetMyPrivateField(int val)
{
_field = val;
}
or you can take pass the value in with the constructor
public class MyClass
{
private int _field;
public MyClass(int val)
{
_field = val;
}
}
Is it possible to set value via class object.
It is indeed possible to do this using reflection:
public class Program
{
public static void Main()
{
MyClass cl = new MyClass();
var fi = cl.GetType().GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
fi.SetValue(cl, 10);
Console.WriteLine(fi.GetValue(cl));
}
}
But there is probably a reason for the field being private so you shouldn't do this. But you can.
This violate Object Oriented concepts which used in C#
so, you shouldn't do that and save encapsulation concept
by using
Property
public Get{get=>field;set=>field=value;}
Setter & Getter
Constructor
public MyClass(int field) {this.field = field;}
It really depends on how much encapsulation you want to use. Realistically the best way to think about this is to go for the way that limits the accessibility of the variable as much as possible.
You want a variable/property to be read/write outside of the class
Use a public property. This gives you read and write access. There is no need for a backing variable as it's all readable/writeable anyway.
public MyClass
{
public int Field {get; set;}
}
You want a variable/property to be readable outside of the class, but not writeable
There is a couple of ways to skin a cat here. One way is to still use a property but make the setter private, meaning it can only be set inside the class.
public MyClass
{
public int Field {get; private set;}
public MyClass(int field)
{
Field = field;
}
}
I prefer to have a backing readonly variable if it's only to be set inside the constructor and it will never change.
public MyClass
{
private readonly int _field;
public int Field {get=>_field;}
public MyClass(int field)
{
_field = field;
}
}
You want a variable to be passed into a class but not readable/writeable from that point
You should just use a private readonly variable.
public MyClass
{
private readonly int _field;
public MyClass(int field)
{
_field = field;
}
}
When I was in university 6-8 years ago, I learned that it was common practise to have public get and set methods but private variables when using Java. However these days, when I use C#, I realise that a lot of the common class variables have public accessibility, e.g. String.Length.
Is it common practise in C# to make variables public (so is it widely accepted that people can program in such a manner)?
Thanks
String.Length isn't really a public variable. In C#, it's common to use getters this way:
class Foo
{
private int _bar;
public int Bar
{
get { return _bar; } // getter
set { _bar = value; } // setter
}
}
// ...
Foo foo = new Foo();
foo.Bar = 42;
In other words, string.Length is only a getter for the read only variable string._lengh.
Often, it's also a good practice to mark the setter as private meaning that only the where your setter is declared can set the value for your property, and any other derived class can access it with the getter method.
So there are a couple of ways to declare properties with:
Use the prop shortcut and hit Tab twice (Code Snippets in Visual Studio). This produces:
public int Foo{ get; set; }
Use the propg shortcut + Tab twice to declare the setter as private. Looks like this:
public int Foo{ get; private set; }
Use the full implementation in using the shortcut propfull which will give you:
private int Foo;
public int MyProperty
{
get { return Foo;}
set { Foo = value;}
}
You can also make a public variable readonly, instead of making its setter private:
class Foo
{
public readonly int Bar; // Bar can only be initialized in the constructor
public Foo()
{
this.Bar = 42;
}
}
I'm a bit confused.
I have the following code:
public class MyClass
{
public string DoSomething(string TheString)
{
int TheID;
string TheString = "";
}
}
This works fine; it compiles. However, why doesn't this work?
public class MyClass
{
public string DoSomething(string TheString)
{
private int TheID {get;set;}
private string TheString {get;set;}
}
}
I want to make these variables private. What do I need to change?
Private variables are only valid at the class level:
public class MyClass {
private int TheID {get;set;}
private string TheString {get;set;}
public string DoSomething(string TheString) {
}
}
Variables defined inside a method are local in scope and they only exist inside that method. Nothing outside the method can access them. It makes no sense to declare a local variable as private.
They are scoped inside the method - you can't access them outside of it. You can think of them as being private.
If both get and set are compulsory in C# automatic properties, why do I have to bother specifying "get; set;" at all?
Because you might want a read-only property:
public int Foo { get; private set; }
Or Write-only property:
public int Foo { private get; set; }
ERROR: A property or indexer may not be passed as an out or ref parameter
If you didn't specify {get; set;} then the compiler wouldn't know if it's a field or a property.
This is important becasue while they "look" identical the compiler treats them differently. e.g. Calling "InitAnInt" on the property raises an error.
class Test
{
public int n;
public int i { get; set; }
public void InitAnInt(out int p)
{
p = 100;
}
public Test()
{
InitAnInt(out n); // This is OK
InitAnInt(out i); // ERROR: A property or indexer may not be passed
// as an out or ref parameter
}
}
You shouldn't create public fields/Variables on classes, you never know when you'll want to change it to have get & set accessors, and then you don't know what code you're going to break, especially if you have clients that program against your API.
Also you can have different access modifiers for the get & set, e.g. {get; private set;} makes the get public and the the set private to the declaring class.
Just thought I would share my findings on this topic.
Coding a property like the following, is a .net 3.0 shortcut call “auto-implemented property”.
public int MyProperty { get; set; }
This saves you some typing. The long way to declare a property is like this:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
When you use the “auto-implemented property” the compiler generates the code to wire up the get and set to some “k_BackingField”. Below is the disassembled code using Reflector.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
[CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
disassembled C# code from IL
Also wires up a method for the setter and getter.
[CompilerGenerated]
public void set_MyProperty(int value)
{
this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
return this.<MyProperty>k__BackingField;
}
disassembled C# code from IL
When you declare a read only auto-implemented property, by setting the setter to private:
public int MyProperty { get; private set; }
All the compiler does flag the "set" as private. The setter and getter method say the same.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
private [CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
disassembled C# code from IL
So I am not sure why the framework require both the get; and set; on an auto-implemented property. They could have just not written the set and setter method if it was not supplied. But there may be some compiler level issue that makes this difficult, I don't know.
If you look at the long way of declaring a read only property:
public int myProperty = 0;
public int MyProperty
{
get { return myProperty; }
}
And then look at the disassembled code. The setter is not there at all.
public int Test2
{
get
{
return this._test;
}
}
public int get_Test2()
{
return this._test;
}
disassembled C# code from IL
Because you need some way to distinguish it from plain fields.
It's also useful to have different access modifiers, e.g.
public int MyProperty { get; private set; }
The compiler needs to know if you want it to generate a getter and/or a setter, or perhaps are declaring a field.
If the property didn't have accessors, how would the compiler separate it from a field? And what would separate it from a field?
Well, obviously you need a way of disambiguating between fields and properties. But are required keywords really necessary? For instance, it's clear that these two declarations are different:
public int Foo;
public int Bar { }
That could work. That is, it's a syntax that a compiler could conceivably make sense of.
But then you get to a situation where an empty block has semantic meaning. That seems precarious.
Since no one mentioned it... you could make the auto-property virtual and override it:
public virtual int Property { get; set; }
If there was no get/set, how would it be overridden? Note that you are allowed to override the getter and not the setter:
public override int Property { get { return int.MinValue; } }
Also, because ever since C# 6.0 (in Visual Studio 2015, at the time of this answer available in version Ultimate Preview) you may implement a true read-only property:
public string Name { get; }
public string Name { get; } = "This won't change even internally";
... as opposed to currently imperfect workaround with public getter/private setter pair:
public string Name { get; private set; }
public Constructor() { Name="As initialised"; }
public void Method() { Name="This might be changed internally. By mistake. Or not."; }
Example of the above below (compiled and executable online here).
using System;
public class Propertier {
public string ReadOnlyPlease { get; private set; }
public Propertier() { ReadOnlyPlease="As initialised"; }
public void Method() { ReadOnlyPlease="This might be changed internally"; }
public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); }
}
public class Program {
static void Main() {
Propertier p=new Propertier();
Console.WriteLine(p);
// p.ReadOnlyPlease="Changing externally!";
// Console.WriteLine(p);
// error CS0272: The property or indexer `Propertier.ReadOnlyPlease' cannot be used in this context because the set accessor is inaccessible
// That's good and intended.
// But...
p.Method();
Console.WriteLine(p);
}
}
Other tasty news about C# 6.0 available as official preview video here.