I"m a little confused with this short hand. Does this allow me to acesss myVar and set myVar like so?
object.myVar = 5;
newNum = object.myVar;
I don't get this.
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
No, what this means is that you have a "hidden" private integer called myVar that nobody outside the class can see, but people from the outside can only see a property called MyProperty, that happens to redirect to myVar, but they won't know it !
from the inside, you can do :
this.myVar = 12;
int test = this.myVar; /*(this. would actually be optionnal)*/
from the outside, if myInstance is an instance of your class, people can do this :
int test = myInstance.MyProperty;
myInstance.MyProperty = 12;
The point of properties is to hide the private members, and control how they are accessed.
It does not allow you, that is the point. You access the private variable via the public property.
In version 3.0 and above you can also do:
public int MyProperty { get; set; }
And access them like so:
object.MyProperty = 5;
newNum = object.MyProperty;
No it won't be redundant
public int MyProperty { get; set;}
This creates a public and a private variable.
Outside classes can command it but there is a hidden private variable that will use the get set method. This is still safe since it is the class itself that will change the values and not some other method from outside.
No it allows you to access your variable myVar by using this:
object.MyProperty = 5;
newNum = object.MyProperty;
you could get rid of the backing variable entirely and do this though:
public int MyProperty
{
get; set;
}
which will still allow you to access your property like the first code section in my answer.
public int MyProperty { get; set; }
wouldn't this be redundant since if MyProperty is public it can already be 'get' and 'set'?
Related
As a very simplified and stupid example of what I'm dealing with, suppose I had the following class with a simple static int property:
public class MyClass
{
public static int MyVar { get; set; }
}
So, if I wanted to set that property via code, it would be easy enough with something such as:
MyClass.MyVar = 2;
But, how could I take care of (again, to simplify the example) passing in a string and have it converted to an int?
The only way I could think of doing it is to create a helper method such as:
public class MyClass
{
public static int MyVar { get; private set; }
public static void SetMyVar(string sMyVar)
{
MyVar = int.Parse(sMyVar);
}
}
And then in code run:
MyClass.SetMyVar("2");
I would love to know if there was a better way to accomplish this than having to add in that extra method.
Although you definitely shouldn't do this because it's confusing to read, you could create the property this way
class MyClass
{
private static int _property = 0;
public static object Property
{
get
{
return _property;
}
set
{
_property = Convert.ToInt32(value);
}
}
}
You would have to cast this to an int whenever you wanted to use it as an integer but this is best I could think of.
is this what you were trying to do?
class newclass
{
private static int MyVarValue = 0;
public static int MyVar
{
get;
set
{
MyVarValue = Convert.ToInt32(value);
}
}
}
This would not compile because the value that a property gets set to has to be of the same type as the property itself. But if you are taking a list of objects in a constructor and assigning them to the properties, there you can do something like this...
class newclass
{
private static int MyVarValue = 0;
public newclass(List<object> startingList)
{
MyVarValue = Convert.ToInt32(startingList[0]);
}
}
You can use the compiler's method overload resolution to pick a SetMyValue method depending on the type of the argument. Inside each SetMyValue method you have a mechanism to convert all of the different input values to the same underlying type.
Doing this is probably a bad idea - but here goes anyway. It doesn't have quite the semantics that you're asking for but it's close:
//A class with multiple 'set' methods that will silently handle
//type conversions
class MyClass{
private int myValue;
public int MyValue { { get return this.myValue; } }
public void SetMyValue(int value){
this.myValue = value;
}
public void SetMyValue(string value){
this.myValue = Convert.ToInt32(value);
}
}
In statically typed languages, switching types silently in a way that loses information is not a very wise idea. There are other, dynamically typed languages that let you play fast and loose with types but C# is not one of them. You have to go out of your way in C# to get dynamic typing.
Doing this is probably a pain in the butt from a maintenance standpoint. I would put some more thought into the underlying problem that you're trying to solve that lead to this question.
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 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.