How is this code able to compile and run error free?
private void queueToolStripMenuItem_Click(object sender, EventArgs e)
{
//Class name MDPlayer
Playlist.QueueList.Add(tempPlayList[songView.SelectedIndex]);
Playlist.GetQueue = null;
QueueCombobox.Items.Clear();
foreach (PlayListData pld in Playlist.QueueList)
{
QueueCombobox.Items.Add(pld.Track);
}
}
class Playlist
{
private static List<PlayListData> queueList = new List<PlayListData>();
public static List<PlayListData> QueueList
{
get { return queueList;}
}
}
How am I able to add to queueList that is private through the public property QueueList that doesn't even have a setter?
You are able to call methods on the return value of a property getter.
Your property getter returns a List<>. List<> defines the Add method. Thus you can call the Add method on the List<> that you asked for.
Note that you can not assign a new value to the listQueue from outside the PlayList class because it is private.
Also, you can not assign a new value to the ListQueue property because it has no setter accessor.
This will fail: PlayList.QueueList = new List<PlayListData>();
Because you're adding to the list via the getter. You're not setting the underlying private variable to anything. You can do QueueList.Add(), but not QueueList = newList.
When you get a value from the getter, it returns the whole class and that class is alterable. You only need a setter when you want to set the whole variable to an entirely different class.
Summary
You only need to use a setter when setting the whole variable.
Can
Playlist.QueueList.Add(tempPlayList[songView.SelectedIndex]);
Cannot
Playlist.QueueList = new List<PlayListData>();
Related
I am not sure, but it seems i can not set a Property of a List?
The code in the (set) section does not get executed, debugger does not stop in the set when placing a break-point.
if a list property is dealt with differently? and if there is a link of some reading on this subject.
class test
{
public test()
{
id = new List<string>();
_id = new List<string>();
}
private List<string> _id;
public List<string> id
{
get { return _id; }
set
{
_id = value;
}
}
}
test t = new test();
t.id.Add("one");
The code in the (set) section does not get executed, debugger does not stop in the set when placing a break-point.
It appears that your question is, "why is the set accessor not called when I do: t.id.Add("one");"
The reason is simply that the set accessor is for the List itself. Your code is not setting t.id to a new List<string>, rather it is calling the .Add method of the object returned from the t.id property.
So the execution would look something like:
The get accessor is called when you do t.id, and it returns the instance of _id
The .Add method of _id is then called, and the string "one" is added to the private backing field _id
Note that in your existing code, the set does get called from the constructor, when you explicitly set the id to a new List.
You've stated that your goal is "to change some other properties when I add an item to id". There are a few ways to do this, but probably the simplest to understand and implement is:
In the get accessor for the list, return a copy of the list. This prevents clients from adding an item directly through the Add method. Also note that there is no need for a set accessor.
Provide a separate AddId method on your class, which is what the clients would have to call to actually add an item. This is where you have the opportunity to do something else when items are added to the list.
For example:
class Test
{
private readonly List<string> id = new List<string>();
// Return a copy of our private list
public List<string> Id => id?.ToList();
public void AddId(string newId)
{
id.Add(newId);
// do something else here when we add a new item
}
}
Note that this might cause some confusion for clients of your class, because they can still do test.Id.Add("invalid item"); and they won't get any error, but it also won't add anything to the private list. If they want to add something to the list, they have to call the AddId method:
t.AddId("one");
Code:-
(Note:- here I'm using read-only word means that property has only get accessor.)
Class Test
{
public List<string> list {get;}
public string name{get;}
public Test ()
{
list =new List<string>();
}
}
Main()
{
Test test =new Test();
test.list.add("c#"); //no error
test.name="Jhon"; //here I get compilation because property name is read-only
}
If you see above snippet. Test class contain two property which is name and list. In main method I'm creating object of test class to access these properties. So if you see if I try to set value to name property then I'll get compilation error because name property is read only. Similarly if you see another property 'list' that is also read-only if I use add property of List class then without error I'm able to add in list.
So I'm not getting how this happen.
That's because the set would refer to setting the List object, the actual instance of the collection. The List itself, when returned, is not readonly. If you want it to be readonly, you can do something like:
private List<string> list;
public ReadOnlyCollection<string> List {get => list.AsReadOnly()}
You have a misunderstanding of how a "read only" property would work.
If your code looked like this:
Test test = new Test();
test.list.Add("c#"); //no error because you are not 'setting' the object
test.list = new List<string>(); //Error here because you ARE setting the object
Add() is just a method of a List<T>, you are modifying the object not setting the property to something else.
If you want your collection to be "read only" you can use the ReadOnlyCollection interface. You can manage a private list internally and only expose through the public ReadOnlyCollection. Your desired functionality was never made clear so I wouldn't know what to suggest beyond what I have.
This is because in case of a string you return a copy of the instance - you can not assign to it.
Why .NET String is immutable?
In case of a List<T> you return a reference to an instance, which is not constant in your case - it is possible to change it.
To prove that yourself, you can do something like :
class Test
{
private string val;
public ref string Val {get {return ref val;}}
}
void Main()
{
Test t = new Test();
t.Val = "a";
Console.WriteLine("t.Val is - " + t.Val);
}
Observe special ref keyword I used in string property, to denote that string reference has to be returned and not a copy of it.
C# Concepts: Value vs Reference Types (Joseph Albahari)
public List<string> list {get;}
That means, it causes the error if you do the same action with name.
test.list = new List<string>();
test.list to get the list object and you call the method Add of the list object. So it's normal.
I have a class testClass
public class testClass
{
public int firstInt;
public int SecondInt { get; set; }
}
On an event in my page _Default, I am creating an object and trying to set the properties.
protected void Button1_Click(object sender, EventArgs e)
{
testClass objtestClass = new testClass();
objtestClass.firstInt = 1;
objtestClass.SecondInt = 2;
}
Value got set in both correctly. But firstInt and SecondInt behaves different. See the image.
Why both appears in different color?
Here
public class testClass
{
public int firstInt; // a class variable/Field
public int SecondInt { get; set; } // property
}
Variables/Field: A variable corresponds directly to a memory location. You define a variable with a single declaration statement. A variable can be a local variable, defined inside a procedure and available only within that procedure, or it can be a member variable, defined in a module, class, or structure but not inside any procedure. A member variable is also called a field
Properties: A property is a data element defined on a module, class, or structure. You define a property with a code block between the Property and End Property statements. The code block contains a Get procedure, a Set procedure, or both. These procedures are called property procedures or property accessors. In addition to retrieving or storing the property's value, they can also perform custom actions, such as updating an access counter.
See the Msdn link here http://msdn.microsoft.com/en-us/library/sk5e8eth.aspx for explanation
Also this question has a wonderful explanation here What is Difference between Property and Variable in C#
'firstInt' is a class field (variable) while 'SecondInt' is a .NET property. You can encapulate the processing SecondInt within your class if you need to by expanding the get and set methods.
The way SecondInt appears is the sign for properties. and the way you did it as:
public int SecondInt { get; set; }
makes it the property. properties are easy to use (no need to call setter/getter etc.). Now SecondInt behaves as a property of your testclass.
Edit:
By refactoring in visual studio, you can automatically (or manually) do this:
private string m_MyProperty;
public string MyProperty
{
get { return m_MyProperty; }
set { m_MyProperty = value; }
}
This way, your MyProperty property has been created, which sets and gets value for your private m_MyProperty string. and you can use it as:
String x = tstobj.MyProperty;
tstobj.MyProperty = x;
Actually when you write a property like this:
public int second {get; set;}
called auto property, C# automatically uses a private variable like
private int _second;
(much like your first variable)
and use your property as below
public int second{ get{ return _second;} set{ _second = value;} }
something like getSecond and setSecond methods in java.
so Properties are like two separate methods to getting and setting, and can has a backing field (a private variable) for storing data. Properties used for controlling access to internal data of class.
Do I need to declare a class-level variable to hold a property, or can I just refer to self.{propertyname} in the getter/setter?
In other words, can I do this? (where I haven't defined mongoFormId anywhere):
public string mongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
You can either use automatic accessors or implement your own. If you use automatic accessors, the C# compiler will generate a backing field for you, but if you implement your own you must manually provide a backing field (or handle the value some other way).
private string _mongoFormId;
public string mongoFormId
{
get { return this._mongoFormId; }
set
{
this._mongoFormId = value;
revalidateTransformation();
}
}
UPDATE: Since this question was asked, C# 6.0 has been released. However, even with the new syntax options, there is still no way to provide a custom setter body without the need to explicitly declare a backing field.
You need to set a field variable and store the value there, if you're going to use custom getter and setter.
With the code you have right now you will be running into a stack overflow exception. When you assign something to mongoFormId, you'll execute the line this.MongoFormId = value;. This is an assignment to mongoFormId, resulting in executing the line this.MongoFormId = value;, and so on. It won't ever stop.
The correct way is a field:
private string _mongoFormId;
public string mongoFormId {
get { return this._mongoFormId; }
set {
this._mongoFormId = value;
revalidateTransformation();
}
}
You should have a backing variable. Take a closer look:
get { return this.mongoFormId; }
Is going to call the getter on mongoFormId, which will call that code again, and again, and again! Defining a backing variable will avoid the infinite recursive call.
Check MSDN Properties Overview
While a property definition generally includes a private data member,
this is not required. The get accessor could return a value without
accessing a private data member. One example is a property whose get
method returns the system time. Properties enable data hiding, the
accessor methods hide the implementation of the property.
You can do it both the ways.
If you want to have a class level member variable then do it this way -
public class sampleClass
{
private string _mongoFormId;
public string mongoFormId {
get { return _mongoFormId; }
set {
_mongoFormId = value;
revalidateTransformation();
}
}
}
Or do this simple in class, if no need for revalidateTransformation() execution call there
public class sampleClass
{
public string mongoFormId {get; set;}
}
This won't work since you get a recursive call to the property.
If I'm not mistaken, the result will be a StackOverflowException.
You must use a variable.
private string mongoFormId;
public string MongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
If you don't have to execute revalidateTransformation, you can use the auto-property.
This will create a backingfiled for you behind the scene.
public string MongoFormId { get; set; }
With the code you wrote, you are creating a recursive endless loop on both the get and set. The this keyword refer to the current class, not the property you are in.
So yes, you need to declare a private field. And to avoid confusion, create properties following the MSDN Naming Guideline (Use Pascal case for properties, camel case for private fields). And please do the same for your methods, it should be RevalidateTransformation instead of revalidateTransformation if you follow the C# convention instead of java's.
private string mongoFormId;
public string MongoFormId
{
get
{
return mongoFormId;
}
set
{
mongoFormId = value;
RevalidateTransformation();
}
}
public string mongoFormId {
get {
return this.mongoFormId;
}
set {
this.mongoFormId = value;
revalidateTransformation();
}
}
this way you have the Function recursive on all paths
The only way i see is to use a private data member. As other boys tells.
Consider the class:
public class foo
{
public object newObject
{
get
{
return new object();
}
}
}
According to MSDN:
Properties are members that provide a flexible mechanism to read,
write, or compute the values of private fields. Properties can be used
as though they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily
And:
Properties enable a class to expose a public way of getting and
setting values, while hiding implementation or verification code.
A get property accessor is used to return the property value, and a
set accessor is used to assign a new value. These accessors can have
different access levels. For more information, see Accessor
Accessibility.
The value keyword is used to define the value being assigned by the
set indexer.
Properties that do not implement a set method are read only.
while still providing the safety and flexibility of methods.
Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?
edit removed readonly from property
edit2 also would like to clarify that this is not the best use for a property but its done to try and illustrate the question more effectively.
You return a new object on each access to the property and that is not the expected behavior of properties. Instead you should return the same value each time (e.g. a value stored in a field). A property getter is simply glorified syntax for a method that returns a value. Your code compiles into something like this (the compiler creates a getter by prefixing the property name with get_ which is then emitted as IL):
public class foo
{
public object get_newObject()
{
return new object();
}
}
Each call to the getter will create a new object that foo doesn't know about or has access to.
Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?
No.
Property using a backing field:
class Foo {
readonly Object bar = new Object();
public Object Bar { get { return this.bar; } }
}
Using automatic properties:
class Foo {
public Foo() {
Bar = new Object();
}
public Object Bar { get; private set; }
}
A property is accessed using the same easy syntax as a public field. However, by using a property you can add code to the getter and the setter allowing you to do stuff like lazy loading in the getter or validation in the setter (and much more).
Under the hood, your property will simply be calling a function named get_newObject() that looks like this:
public object get_newObject()
{
return new object();
}
Since that is the case, it will always return a new object every time it is invoked.
If you want to retain a reference to the object, then I would recommend creating a private field to hold the data and having the property access that field, like so:
private object myObject;
public object newObject
{
if(myObject == null)
{
myObject = new object();
}
return myObject;
}
Since your property doesn't define set, and your field is private, newObject is basically eradonly outside of the containing class.
Properties in C# are "syntactic sugar". The code within the get block of a property is in fact put into a hidden get_PropertyName() method, and the set block into a hidden set_PropertyName() method. In the case of your code, the following method will be created:
public object get_newObject()
{
return new object();
}
You can see these hidden methods if you view the compiled assembly using Reflector, or ildasm.
When the property is used, the C# compiler converts any "get" accesses of your property into calls of the get_newObject() method. As an example:
If you were to write the following:
var foo = new foo();
var aNewObject = foo.newObject;
The compiler would convert that to:
var foo = new foo();
var aNewObject = foo.get_newObject();
So, in answer to your other question, the newly created object returned when someone "gets" the property won't be stored within your foo instance, the caller will simply get a new object every time.
Not exactly. Properties are just syntactic sugar so that you don't have to write accessor methods (like Java).
So this:
private int _myInteger;
public int MyInteger
{
get { return _myInteger; }
set { _myInteger = value; }
}
is equivilant to this:
private int _myInteger;
public int GetMyInteger()
{
return _myInteger;
}
public void SetMyInteger(int value)
{
_myInteger = value;
}
and it gets better with this, which is also equivilant:
public int MyInteger { get; set; }