I'd like to trigger a method every-time a value is changed in my list.
The top answer on other questions related to this is to use a property, which I have (example below)
However, I think it would help me prevent any accidental bugs if I deny anything other than that property having access to the 'core' list it changes (for lack of better understanding what the term is) .
Below is my example property with a get and set accessor.
private List<Things>myPrivateList; // Only the Property should be able to access
private List<Things>MyPrivateList // Only the class its in can touch this
{
get { return myPrivateList; }
set
{
myPrivateList = value;
coolMethodThatNeedsToRunEverytime();
}
}
public List<Things>getMyPrivateList // Any class outside can read this
{
get { return myPrivateList; }
}
I might be going about this the wrong way though, it would useful to know if you have any suggestions for what I'm trying to achieve. Thanks very much in advance for any advice / example you may have.
You can do what you want with one property :
public List<Things>MyPrivateList // Only the class its in can touch this
{
get { return myPrivateList; }
private set
{
myPrivateList = value;
coolMethodThatNeedsToRunEverytime();
}
}
Doing this, the setter will be private and the getter public
Related
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.
I am very new to .net .. I want to know What is Get, Set Properties ? I can't understand this? Please could anyone help me with some examples?
Get is called Accessor and Set is called Mutators in .Net
in Oops to preserve DataAbstraction concept we keeps Data member private in class.
now to access that data members from outside world we need some mechanism through which we can use it.
for this we define property which contains Accessor and Mutator.
with this we can give tremendous data abstraction.
you need them to have control over your object private fields values. for example if you don't wanna allow nulls or negative values for integers. Also, encapsulation is useful for triggering events on change of values of object members. Example
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
and also another implementation of read only properties could be as follows
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
}
These are mutator method's, check Wikipedia for example and explanation, don't have to copy/paste that ;)
http://en.wikipedia.org/wiki/Mutator_method
You use properties as part of classes to store data.
public class MyClass
{
string ClassName { get; set;}
}
If you instantiate this class, you will be able to set its ClassName field.
These properties are then used within the class for methods to manipulate.
The Set will allow modification of the property. The Get will allow extraction of the data from the property. They are for property access.
I suggest you read some intro books on c# / vb.net to understand how to program first.
This will then enable you to understand more about what you asking.
Is there a way to do something like this in C#:
public class Class2 {
public string PropertyName1 { get
{
return this; //i mean "PropertyName1"
}
set {
this = value;
DoAdditionalFunction();
}
}
Because I need to call additional function in the "set" I need to have an extra private field like
private string _propertyName1;
public string PropertyName1 { get
{
return _propertyName1;
}
set {
_propertyName1= value;
DoAdditionalFunction();
}
I don't want to use additional property like _propertyName1. Is there a way to accomplish this or any best practices?
No - if you need any behaviour other than the most trivial "set a field, return the field value", you need to write "full" properties. Automatically implemented properties are only a shorthand for trivial properties.
Note that you haven't really got an "extra" private field, in terms of the actual contents of an object - it's just that you're explicitly declaring the private field instead of letting the compiler do it for you as part of the automatically implemented property.
(It's not clear what your first property is trying to do - setting this in a class is invalid, and you can't return this from a property of type string unless you've got a conversion to string...)
class StyleProperty<T>
{
static readonly StyleProperty<Object> INHERIT ;
T value;
public T Value
{
get { return this.value; }
set { this.value = value; }
}
}
Hello..
The above class sometimes should have the value INHERIT when value should not be used.. As
c# doesnt allow overloading Properties i cant set Value=StyleProperty.Inherit. i must be of type T.
Any idea what to do there?
After reading your comments, what about this:
class StyleProperty<T>
{
T _Value;
public StyleProperty(T inheritedValue)
{
_Value = inheritedValue;
}
public T Value
{
get { return this._Value; }
set { this._Value = value; }
}
}
Your first problem is how should the inherited value flow into the concrete instance? The only way i can think of would be the constructor. If the user doesn't like this value he can simply change it (to maybe the same value).
If you would use for inheritance some kind of global variable (but that wouldn't be inheritance, that would be a default value) you could also think about using a boolean flag which will be checked in the getter to find out if the backing store or the default should be used and it will set always to the opposite of its initial state within the setter.
class StyleProperty<T>
{
T _Value;
bool _UseBackingStore;
public T Value
{
get { return _UseBackingStore ? this._Value : INHERIT; }
set { this._Value = value; _UseBackingStore = true; }
}
}
Update
To get a skin support into your application i think you need to take a different approach. All forms and gui controls you are using should implement some kind of interface (e.g. ISkin). Also your application should have some kind of SkinSelector. This one holds all informations about coloring, fonts, etc and it also gets a reference to the MainForm. Within the constructor it recursively runs through the Controls property of the form and checks if there are any controls implementing your interface (simply using as ISkin and check for null). If it is skinnable, simply set the colors, fonts, etc. of the control as defined within you SkinSelector. Sounds quite easy but the problem is, that you have to derive all gui controls and add your interface to them. So this is not such a complicated thing, but maybe a lot of work. Maybe you can test if Generics can help you out by using a SkinWrapper<T> where T : Control and an extension function like ISkin ToSkinnableControl(this Control control)). But this will only work if you need to change a few common properties, that are the same for all controls. If you need more skin control e.g. for the DataGridView or a ComboBox i think derivement is the only way to help you out.
Not exactly sure what you're asking for, but you can define a default value for a property like this:
[DefaultValue(<Value>)]
public T Value
{
get { return this.value; }
set { this.value = value; }
}
Can anyone clearly articulate when you use a field and when to use a property in class design?
Consider:
public string Name;
Or:
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
I realize that the second method is more proper and flexible, so that's what I try to use, generally.
But then why do I see people use the first method? Are they just lazy, or is there some specific situation where it's the correct choice? Is it just a matter of preference?
Well in C# 3.0 you can actually write:
public string Name {get; set;}
Which allows you to be proper and lazy.
Generally speaking, with properties, you get proper encapsulation. You have the choice to allow setting a value, or getting it, or both. Using a public member, you don't have that option.
It's probably one-part preference, and one-part how your team decides to handle quick and dirty class definitions, but I would say, use properties for get/sets.
To answer
Can anyone clearly articulate when you use an attribute and when to use a property in class design?
You shouldn't ever use a public attribute. You should always use a property instead. It's safer and more flexible. That said, people will be lazy, and just use a public member. However, with C# 3.0 you can use a more terse syntax to define properties, which should satisfy your inner laziness.
Simply type prop and hit <tab> to expedite the laziness in adding a property.
Just some additional information to Alan's reply:
public string Name {get; set;}
is the same as
private string _Name;
public string Name{
get { return _Name; }
set { _Name = value; }
}
If you want to disallow the set function of Name, you can have
public string Name {get; private set;}
Properties are more maintainable than fields, you can encapsulate logic in your setters/getters, allowing you to hide the implementation.
They also make refactoring easier.
More information:
Property Usage Guidelines
Field Usage Guidelines
Using properties you can control it's security:
public string Foo { protected get; private set; }
Properties gives easy way to raise events:
public string Foo
{
get { return _foo; }
}
set
{
bool cancel = false;
if(BeforeEvent != null) // EventHandler<CancelEventArgs> BeforeEvent
{
CancelEventArgs e = new CancelEventArgs();
BeforeEvent(this, e);
cancel = e.Cancel;
}
if(!cancel)
{
_foo = value;
if(AfterEvent != null) // EventHandler<EventArgs> AfterEvent
{
AfterEvent(this, new EventArgs());
}
}
}
Also I often use code like this:
string Foo
{
set
{
IsFooSet = value != null;
}
}
bool IsFooSet
{
get { return _isFoo; }
set
{
_isFoo = value;
if(value) // some event raise or controls on form change
}
}
When you make the field public, you allow the user to do whatever they want to do to the field. They can assign unexpected values, invalid values, values that can cause overflow, etc.
With the property, you have control over whether to allow the setting of new values to the field, massaging the value before storing it, notifying interested parties about the change of the field's value, etc. And the same idea for returning value through the getter. For .NET framework from 2.0 up, you can set the accessor for the getter, setter. Say, you only want the user to only have read access to the field, then you make the getter public, but the setter private or protected.
In addition to the already-given reasons for preferring properties, there's also lots of cool stuff in System.ComponentModel to do with data binding and change notification that only works with properties, rather than fields. For example, look at the documentation around PropertyChangedHandler.
A property like defined above acts like a getter and setter. The only benefits of using a property is that you can treat it like a variable with access restriction.
public string Name { get; private set; }
This property can be accessed publicly, but can only be set privately. (You wouldn't want anyone changing your name with out your consent now would you! ;) )