I am writing following code,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyObject
{
class Program
{
private readonly int a = 20;
private readonly int b;
public int propa{get;private set;}
public int propb { get; private set; }
public Program(int tmp)
{
b = tmp;
}
static void Main(string[] args)
{
Program obj1 = new Program(30);
Console.WriteLine(obj1.propa); // Console.WriteLine(obj1.a);
Console.WriteLine(obj1.propb); // Console.WriteLine(obj1.b);
Console.Read();
}
}
}
After executing the above i got o/p as follows,
0
0
And when I change the code by replacing two commented statements printing direct member variables I got output as,
20
30
Why is so?
As far I know about properties they are associated with their definition in order the member variables are declared.
You have confusion about auto property, so:
private readonly int a = 20;
private readonly int b;
public int propa{get {return a; }}
public int propb { get {return b;} private set {b = value;} }
now this will print 20, 30
There are two ways to define properties in C#.
The first, the traditional way;
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
the second, the auto-property;
public int MyProperty {get;set;}
The first contains a backing variable that you reference in the property accessor. The second implicitly creates a backing variable, because the developers of the language understood that there are a lot of cases where you just need a property!
You can put scope on the auto-property, because you might want to prevent people from setting the value, but internally to the object you should be able to update the value of it.
"As far I know about properties they are associated with their
defination in order the member variables are declated."
Just to clarify all of what you were asking, unless I am reading this statement incorrectly, you're thinking that if you declare variable a and b and the property a and property b that they'll be associated. This is an incorrect assumption.
propa and a are not associated in your example. The compiler is making them auto-implemented properties. http://msdn.microsoft.com/en-us/library/bb384054.aspx If you want propa associated with a then you'd do:
public int propa{get { return a;} }
You're not initializing either property. You also can't set the value of b from a setter if it's marked readonly. You can implement your own 'readonly' type by just not letting the value get set more than once. (Although it doesn't stay true to the constraint that it needs to be initialized in the constructor)
Try this:
private readonly int a = 20;
public int A { get { return a; } }
private int b;
private bool bInitialized = false;
public int B
{
get { return b; }
private set
{
if (bInitialized) return;
bInitialized = true;
b = value;
}
}
The way your code is written propb and propa CANNOT be set outside the scope of the class. so remove the keyword private from the set keyword
if you wrote this.propb = b in your constructor, then I think it should work more like you are expecting.
Related
I am a bit confused with the get set property in C#.
I have the simple code below:
using System;
class Example
{
int _number;
public int Number
{
get
{
return this._number;
}
set
{
this._number = value;
}
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
The code above using get set properties. However, if I delete the get set code like below code, the results stay the same.
using System;
class Example
{
int _number;
public int Number;
{
}
}
class Program
{
static void Main()
{
Example example = new Example();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
My query is, what is the get set code used for? In the above program, the results are same. Can you give me some simple code which show the get set usage?
In your code, Number is simply a public field, as evidenced by the semicolon (;) at the end.
public int Number;
It is not a property, you just have an empty set of brackets right underneath which led to your confusion. If you were to remove the ; then you would actually have a property that is missing it's get, and would not compile at all.
All properties need to have a getter (setters are optional). If you want to avoid writing them, you can use auto properties, which take care of the backing field without you having to get involved:
public int Number { get; set; } // No field required
Note: A common usage pattern you'll see involving auto properties is the following:
public int Number { get; private set; }
This allows for properties that can be read from anywhere, but can only be modified from within the class they belong to.
EDIT: To answer your question, the main difference between fields and properties is in encapsulation. You can read more about the general differences between fields and properties here.
However, the example you have given has one additional difference, the private set. A normal field can be written from and to throughout the program. A property with a private setter however can only be modified from inside the class it belongs to.
Example:
public class Foo
{
public int Id { get; private set; }
public string Name;
public Foo()
{
this.Id = 1; // This works!
}
}
Here, Name is a field and Id is a property with a private setter. Notice that we modify Id in the constructor and that works, because it is within the class Id belongs to. Moving outside the class however:
var foo = new Foo();
// Field (no get and set):
foo.Name = "test" // Works
string bar = foo.Name; // Works
// Property (get and *private* set)
int i = foo.Id; // Works, because get is public
foo.Id = 2; // Doesn't work, because set is private
Lets have a simple class with an int property
public class SimpleClass {
public int myInt { get; set; }// for having a property and not "public int myInt;", see Jon Skeet remark
}
I instanciate it twice assigning myInt or not
assignedObject = new SimpleClass() { myInt=0};
notAssignedObject = new SimpleClass();
Now by reflection, I query the value of myInt in each case using
Object value;
value=assignedObject.GetType().GetProperties().Where(o=>o.Name.Equals("myInt")).First().GetValue(assignedObject,null)
value=notAssignedObject.GetType().GetProperties().Where(o=>o.Name.Equals("myInt")).First().GetValue(notAssignedObject,null)
I am getting twice 0 for myInt, but I need to be able to differenciate them. How?
Unless you have code to specifically remember the difference between a property which has been initialized with its default value, and one which hasn't been set at all, you can't tell the difference. I have two suggestions, however:
You could make it an int? property, and then check whether the value is null. Of course, it's possible for it to be set to null explicitly, unless you prohibit that, but it may be good enough.
You could keep a separate bool value to know whether or not it's been set explicitly, and just set it in your property setter, along with the value.
Sample code for the second option:
public class SimpleClass
{
private int value;
private bool valueSet;
public int Value
{
get { return value; }
set
{
this.value = value;
this.valueSet = true;
}
}
public bool ValueSet { get { return valueSet; } }
}
If I want a read-only property, I write it like:
public int MyProperty { get { //Code goes here } }
However, the Microsoft example (and a few other examples I've seen) are written like:
public int MyProperty { get; private set; }
Is there any difference between these two, and should I start writing properties like this?
As you can see in your second sample, you can leave out the implementation for a property. .NET will then automatically create a local variable for the property and implement simple getting and setting.
public int MyProperty { get; private set; }
is actually equivalent to
private int _myProperty;
public int MyProperty {
get { return _myProperty; }
private set { _myProperty = value; }
}
Writing
public int MyProperty { get; }
does not work at all, as automatic properties need to implement a getter and a setter, while
public int MyProperty { get; private set; }
leaves you with a property that may return any int, but can only be changed within the current class.
public int MyProperty { get { ... } }
creates a read-only property.
Question is: what do you need? If you already have a member variable that's used within your class and you only want to return the current value using a property, you're perfectly fine with
public int MyProperty { get { return ...; }}
However, if you want a read-only property, which you need to set within your code (but not from other classes) without explicitly declaring a member variable, you have to go with the private set approach.
With private setter you can only assign property value inside of instance when property is without setter you can't set its value anywhere.
If you don't use an explicit member assignment in the property, you'll have to declare a private set at least in order to be able to set a value to this property. Otherwise, you'll get a warning at compile-time saying that your property cannot be assigned.
If you use an explicit member, you'll be able to assign a value to this member directly, without needing to add a private set:
private int member ;
public int MyProperty {
get { return member; }
}
// ...
member = 2;
int anotherVariable = MyProperty; // anotherVariable == 2
public int MyProperty
{
get
{
// Your own logic, like lazy loading
return _myProperty ?? (_myProperty = GetMyProperty());
}
}
A property with only a getter is very useful if you need your own logic behind the access of that property, in particular when you need the property to be lazy loaded.
public int MyProperty { get; private set; }
A property with a private setter is useful if you need the property not te be changed from the outside, but still maintained from within the class.
In both cases, you can have a backing data field for the actual value, but in the former, you'll have to maintain that yourself, and in the latter, it is maintained for you by the generated code.
There is a difference when you access the object with reflection.
public class Foo
{
public string Bar { get; private set; }
}
// .....
internal static void Main()
{
Foo foo = new Foo();
foo.GetType().GetProperty("Bar").SetValue(foo, "private?", null);
Console.WriteLine(foo.Bar);
}
I understand how to create a getters and setters
public myClass
{
public int myVal { get; set; }
// more stuff
}
but I don't understand how to call it later on.
public myOtherClass
{
public myOtherClass()
{
myClass localMyClass = new myClass();
localMyClass.???set??? = 42;
// Intelisense doesn't seem to give any obvious options after I enter
// the period.
}
}
How should I set the value of myVal in localMyClass?
localMyClass.myVal = 42;
Getters and setters let you treat the values like public properties. The difference is, you can do whatever you want inside the functions that do the getting and setting.
Examples:
store other variables
private int _myVal, myOtherVal;
public int MyVal { get; set { _myVal = value; myOtherVal++; } }
make numbers up / return constants
public int MyVal { get { return 99; } set; }
throw away the setter
private int _myVal;
public int MyVal { get { return _myVal; } set { ; } }
In each of these cases, the user will feel like it's just a public data member, and simply type
localMyClass.myVal = 42;
int i = localMyClass.myVal;
The gettors and settors let you make an implementation of your own. Also, as Hogan says, "There are a number of libraries and add-ons [e.g. MVC.NET] that require you to use getter and setter functions" - even if it's for the trivial {get; set;} case.
Set:
localMyClass.myVal = 42
Get:
int variable = localMyClass.myVal;
From the outside, the syntax for accessing getters and setters is indistinguishable from that of accessing variables. Assignments translate into calls of setters, while plain expression uses translate into calls of getters.
In intellisense, the list of getters and setters should open upon placing a dot . after the variable name. Properties should have blue markers to the left of them (as opposed to magenta-colored markers to the left of methods).
You want this
localMyClass.myVal = 42;
to call the setter
and this
varName = localMyClass.myVal;
to call the getter.
Get: var tmp = localMyClass.myVal;
Set: localMyClass.myVal = 2;
I need a field that can be assigned to from where ever I want, but it should be possible to assign it only once (so subsequent assignments should be ignored). How can I do this?
That would not be a readonly field then. Your only options for initializing real readonly fields are field initializer and constructor.
You could however implement a kind of readonly functionality using properties. Make your field as properties. Implement a "freeze instance" method that flipped a flag stating that no more updates to the readonly parts are allowed. Have your setters check this flag.
Keep in mind that you're giving up a compile time check for a runtime check. The compiler will tell you if you try to assign a value to a readonly field from anywhere but the declaration/constructor. With the code below you'll get an exception (or you could ignore the update - neither of which are optimal IMO).
EDIT: to avoid repeating the check you can encapsulate the readonly feature in a class.
Revised implementation could look something like this:
class ReadOnlyField<T> {
public T Value {
get { return _Value; }
set {
if (Frozen) throw new InvalidOperationException();
_Value = value;
}
}
private T _Value;
private bool Frozen;
public void Freeze() {
Frozen = true;
}
}
class Foo {
public readonly ReadOnlyField<int> FakeReadOnly = new ReadOnlyField<int>();
// forward to allow freeze of multiple fields
public void Freeze() {
FakeReadOnly.Freeze();
}
}
Then your code can do something like
var f = new Foo();
f.FakeReadOnly.Value = 42;
f.Freeze();
f.FakeReadOnly.Value = 1337;
The last statement will throw an exception.
Try the following:
class MyClass{
private int num1;
public int Num1
{
get { return num1; }
}
public MyClass()
{
num1=10;
}
}
Or maybe you mean a field that everyone can read but only the class itself can write to? In that case, use a private field with a public getter and a private setter.
private TYPE field;
public TYPE Field
{
get { return field; }
private set { field = value; }
}
or use an automatic property:
public TYPE Field { get; private set; }