Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm just playing around with C# and I'm aksing myself which the proper method is for Getter and Setter. I found something like this with google:
class MyClass
{
Button btnMyButton;
// some code...
public Button getBtnMyButton
{
get
{
return btnMyButton;
}
}
}
is there a 'proper' way? Or is this also okay:
class MyClass
{
Button btnMyButton;
// some code...
public Button getBtnMyButton()
{
return this.btnMyButton;
}
}
Whats the difference?
As Thomas mentioned, those are the same things. You may wonder what the point of getter and setter is in that case and it's mainly syntactic sugar. However, it also means you don't have to create an explicit field as one is created for you in the background. Therefore, you can simply do
public Button MyButton { get; private set; }
The private set; ensures only the class can set its value so it's essentially read-only to outside classes. Removing the private will allow external classes to write to the variable too.
You usually do not add a get/set prefix to properties.
Just write it like that:
private Button myButton;
public Button MyButton{
get{
return myButton;
}
/*set{
myButton = value;
}*/
}
And yes, it means the same in your context. The this. would be required in this scenario:
(Note: This is a stupid example and should only show you the idea)
private Button myButton;
public Button MyButton{
get{
Button myButton = null;
return this.myButton; //<- this. is required or you would end up getting null all the time.
}
/*set{
myButton = value;
}*/
}
Edit:
Adding get/set comes from languages such as C++ or Java where you do not have the luxury of properties. Using get/set indicates a (heavy) operation. And the developer may think about caching the result instead of calling it numerous times. Only use get/set on methods where you want to specify a (heavy) operation. You may even end up using properties instead of methods if it is a very (easy) operation. In Intellisense (Visual Studio) a property is presented just like a field and thus we can assume that there is no operation going on. Thus I will (usually) never cache the result of a property.
On the other hand - if I find a property called GetResultOfImposible.
Then I would propably decide to cache that.
A property named ResultOfImposible sounds less heavy and I wouldn't cache it.
(Maybe I would change my mind after finding a performance peak)
You should think about the naming of the property a little more, because one property can have both a getter and a setter. Consider the following:
public class MyClass
{
private Button btnMyButton;
public Button getMyButton
{
get{ return btnMyButton; }
set{ btnMyButton = value; }
}
}
// in some other class
void ChangeActiveButton(Button newButton)
{
MyClass theThing = GetTheThing();
// This doesn't read well...
theThing.getMyButton = newButton;
}
When you implement property getters and setters, don't prefix the name with 'get' and set'. (To many developers, the words 'get' and 'set' in a method or function imply that the code has to go off and do some work to complete the getting or setting, rather than simply return or assign a value that is already to hand.)
public class MyClass
{
private Button btnMyButton;
// Note that the property just has a name, no prefix.
public Button MyButton
{
get{ return btnMyButton; }
set{ btnMyButton = value; }
}
}
Also note that you can make property getters and setters private even though the property itself is exposed outside the class.
public Button MyButton
{
get{ return btnMyButton; }
private set{ if(null == btnMyButton) btnMyButton = value; }
}
This provides the MyClass with priveliged access to the setter, which can be used to implement any property-specific assignment rules.
You can also use Auto-Implemented Properties, without the additional member variable.
public Button MyButton { get; private set; }
Properties in c# are great. Use them wisely and it will help you create better structured, more easily maintainable code.
Actually a getter/setter is nothing but a method returning/providing the internal value. So while writing
public Button getBtnMyButton
{
get
{
return btnMyButton;
}
}
you actually write a getter-method similar to this one:
public Button getBtnMyButton
{
return this.btnMyButton;
}
So the similar way in java is using methods.
That's the same, this call in is implicit.
The shorter you can do is:
class MyClass
{
// some code...
public Button getBtnMyButton { get; private set; }
}
And I recommend you a bit of reading : Auto-Implemented Properties (C# Programming Guide)
They're basically the same thing. The this pointer refers to the object that is calling the method.
A interesting thing about the this pointer is that it allows you to write set functions like
public void setMyButton (Button myButton)
{
this.myButton = myButton;
}
(Not sure if that's valid C# because I've never worked with it, but you get the idea. That should work in Java/C++)
The difference is in purpose. You should use property, when code just returns some value with few logic or without it at all. Also in general the value should be the same, if setter was not called. When the value is created (not stored) or logic is complex, you should use method. It is a good practice to create self-documented code.
The difference is that:
public Button getBtnMyButton()
{
return this.btnMyButton;
}
is a method, which can accepts inputs parameters and returns an output parameter.
The other:
public Button getBtnMyButton
{
get
{
return btnMyButton;
}
}
is a property. You can see a propery as a "wrapper" around a variable, that allow you to validate the variable value and to perform other kind of stuffs.
Example:
public Button getBtnMyButton
{
get
{
if (btnMyButton != null)
return btnMyButton;
throw new Exception("Button is null!");
}
set
{
if (value == null)
return;
btnMyButton = value;
}
}
Related
I have been using the Breeze.Sharp.BaseEntity base class at work for some time and up until now, have been ok with using their GetValue and SetValue properties for plugging into the INotifyPropertyChanged interface. However, occasionally, it is advantageous to notify of changes to multiple properties at once from a single property. Let me give you a simple example.
Let's say that we have a simple sum to perform. We have an ItemAmount property, an ItemQuantity property, and a Total property. Each time either of the ItemAmount or ItemQuantity property values change, we also want the total to update. Traditionally, we could do that like this:
public double ItemAmount
{
get { return _itemAmount; }
set
{
_itemAmount = value;
NotifyPropertyChanged("ItemAmount");
NotifyPropertyChanged("Total");
}
}
public int ItemQuantity
{
get { return _itemQuantity; }
set
{
_itemQuantity = value;
NotifyPropertyChanged("ItemQuantity");
NotifyPropertyChanged("Total");
}
}
public double { get => ItemAmount * ItemQuantity; }
This would make the Framework also update the value of the Total property as either property changed, as required. However, I can find no such way to call the INotifyPropertyChanged interface using their base class, as unbelievably, they seem to have hidden access to their implementation of it.
So, my question is How can I manually notify the Framework of property changes when using the Breeze.Sharp.BaseEntity class?
Is there some way to connect to their implementation that I haven't worked out yet? When I added my own implementation, it didn't seem to connect with the Framework and did not notify of changes successfully. Many thanks in advance.
There's no simple answer, but the way that I found to do this, was to clone the Breeze.Sharp repository and to make the following changes. In the Breeze.Sharp.Standard solution, open the EntityAspect.cs class and simply add your desired method to raise the PropertyChanged event handler, that is already declared in that class:
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Then, you can call it from your BaseEntity class like this:
public int ItemQuantity
{
get => GetValue<int>();
set
{
SetValue(value);
EntityAspect.NotifyPropertyChanged(nameof(Total));
}
}
Note that changes to the ItemQuantity property are raised inside the SetValue method.
This is the pattern I see everywhere in "legacy" code, but now no one knows why it originated:
public virtual ICollection<SomeClass> SomeProperty
{
get { return m_SomeProperty; }
set
{
if (m_SomeProperty == value)
return;
m_SomeProperty = value;
}
}
My question is, what is the benefit of the "if" check, if any? Can it be simplified to usual
public virtual ICollection<SomeClass> SomeProperty
{
get { return m_SomeProperty; }
set { m_SomeProperty = value; }
}
without any side effects?
Doesn't make much sense if the class doesn't implement INotifyPropertyChanged
But if, you should only fire the PropertyChanged event if a property was changed and not if the same value was assigned. The link contains an example.
If the m_SomeProperty is a private field, this is meaningless. Much better to use auto-property instead:
public virtual ICollection<SomeClass> SomeProperty { get; set; }
In this case, all occurrences of m_SomeProperty should be replaced with SomeProperty.
Side effects are possible if the m_SomeProperty is a property itself. In this case it can have its own setter which should not be triggered if its new value is the same.
I am trying to implement INotifyPropertyChanged for a lot of classes, and each of these classes have lots and lots of properties. I have been following this MSDN documentation for how to implement INofifyPropertyChanged, but their instructions don't seem to be practical in cases where a class has many many properties.
Currently most of my properties use the short hand:
public DateTime? DateClosed { get; set; }
But the documentation says that i need to add the following to each setter method:
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("DateClosed");
This means that I then need to declare a body for the get method and declare private variables to handle the actual getting and setting of properties. Like this:
private DateTime? _dateOfIncident = null;
public DateTime? DateClosed
{
get { return _dateOfIncident; }
set
{
_dateOfIncident= value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("DateClosed");
}
}
Does anyone know a way around this?
A few classes can easily be changed to implement INotifyPropertyChanged. But since you state you have a lot of classes with a lot of properties, it's a real burden to get this done manually or even with templates.
What you really need is a tool that does it for you, so I present you Fody and it's NotifyPropertyChanged plugin. What Fody does is weave some extra code in between your code at compile time. The only thing you have to do is add a single attribute on the classes you want to implement INotifyPropertyChanged and the rest is done for you.
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
}
I'm not sure you're going to find a workaround here. Auto-properties, as you're using them now, are really just a compiler shorthand that get's converted to full properties with a backing field eventually anyway (at least, as I understand it).
The use of INPC is a routine that's sorta separate and apart from the duty of a normal property. It's notifying subscribers (usually, your view XAML) that the property in question has changed or is changing.
tl;dr -- you're not going to get around having to rewrite autoproperties to full properties with backing fields. But toolkits like MVVMLight have some great Visual Studio code snippets to make this relatively fast. Eventually you can even do this:
private string _someString;
public string SomeString
{
get { return _someString;}
set
{
//Set returns bool, so you can trigger other logic on it!
Set(() => SomeString, ref _someString, value);
}
}
This gives you some neat features:
Strong naming (unlike the magic string in your example)
Set only triggers INPC event if the value is different
Set returns boolean so you can perform more action if the value changed
MVVMLight is nice in that you don't have to use all its features, or even implement MVVM pattern. It just has a lot of nice 'tools' you can leverage.
There are a lot of patterns to do it, or you can buy a tool like PostSharp that will do it for you.
For example, here is one method of doing it:
public abstract class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
private Dictionary<string, object> _valueStore = new Dictionary<string, object>();
public event PropertyChangedEventHandler PropertyChanged;
protected T Get<T>([CallerMemberName]string property = null)
{
object value = null;
if (!_valueStore.TryGetValue(property, out value))
return default(T);
return (T)value;
}
protected void Set<T>(T value, [CallerMemberName]string property = null)
{
_valueStore[property] = value;
OnPropertyChangedInternal(property);
}
protected void OnPropertyChanged([CallerMemberName]string property = null)
{
OnPropertyChangedInternal(property);
}
private void OnPropertyChangedInternal(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Which you then inherit from your classes:
public class PlainOldObject : BaseNotifyPropertyChanged
{
public int MyProperty
{
get { return Get<int>(); }
set { Set(value); }
}
}
Which takes care of the backing store and everything for you. You may want to add logic to only call the OnPropertyChangedInternal if the property actually changed (compare references or value), but I'll leave that as an exercise for you.
Simply use the Observable Object class. Instead of creating a DateTime property, you'd create an ObservableObject<DateTime> and you would just bind to DateClosed.Value.
Let's just say that I have:
public Boolean booleanValue;
public bool someMethod(string value)
{
// Do some work in here.
return booleanValue = true;
}
How can I create an event handler that fires up when the booleanValue has changed? Is it possible?
Avoid using public fields as a rule in general. Try to keep them private as much as you can. Then, you can use a wrapper property firing your event. See the example:
class Foo
{
Boolean _booleanValue;
public bool BooleanValue
{
get { return _booleanValue; }
set
{
_booleanValue = value;
if (ValueChanged != null) ValueChanged(value);
}
}
public event ValueChangedEventHandler ValueChanged;
}
delegate void ValueChangedEventHandler(bool value);
That is one simple, "native" way to achieve what you need. There are other ways, even offered by the .NET Framework, but the above approach is just an example.
INotifyPropertyChanged is already defined to notify if property is changed.
Wrap your variable in property and use INotifyPropertyChanged interface.
Change the access of the BooleanValue to private and only allow changing it through one method for consistency.
Fire your custom event in that method
.
private bool _boolValue;
public void ChangeValue(bool value)
{
_boolValue = value;
// Fire your event here
}
Option 2: Make it a property and fire the event in the setter
public bool BoolValue { get { ... } set { _boolValue = value; //Fire Event } }
Edit: As others have said INotifyPropertyChanged is the .NET standard way to do this.
Perhaps take a look at the INotifyPropertyChanged interface. You're bound to come across it's use again in future:
MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
CallingClass.BoolChangeEvent += new Action<bool>(AddressOfFunction);
In your class with the bool property procedure:
public event Action<bool> BoolChangeEvent;
public Boolean booleanValue;
public bool someMethod(string value)
{
// Raise event to signify the bool value has been set.
BoolChangeEvent(value);
// Do some work in here.
booleanValue = true;
return booleanValue;
}
No it is not possible* to get notified about for changes in value of a variable.
You can achieve almost what you want by making the value to be a property of some class and fire events on change as you wish.
*) if your code is debugger for a process you can make CPU to notify you about changes - see data chage breakpoints in Visual Studio. This will require at least some amount of native code and harder to implement correctly for manged code due to hance of objects to be moved in memory by GC.
Is it possible to move the get set methods in another class ?
I'm using an options form which basically reflects all the changes directly in the main form (mostly for changing controls colors,fonts and so on.
The issue starts when you start modifying quite a lot of controls since the main class fills with get set methods, so I was wondering if it's possible to refactor the code to increase the readability of the class a bit, or even better, if it's possible to move the methods in another class somehow (partial classes ?)
Here's a small example of just two controls
public Font TreeFont
{
get { return customTreeView1.Font; }
set { customTreeView1.Font = value; }
}
public Font TextBoxFont
{
get { return customTextBox1.Font; }
set { customTextBox1.Font = value; }
}
public Font MenusFont
{
get { return menuStrip1.Font; }
set
{
menuStrip1.Font = value;
statusStrip1.Font = value;
contextMenuStripForSnippetContent.Font = value;
contextMenuStripTreeViewMenu.Font = value;
}
}
public Color TreeFontForeColor
{
get { return customTreeView1.ForeColor; }
set { customTreeView1.ForeColor = value; }
}
public Color TextBoxFontForeColor
{
get { return customTextBox1.ForeColor; }
set { customTextBox1.ForeColor = value; }
}
public Color TreeFontBackgroundColor
{
get { return customTreeView1.BackColor; }
set { customTreeView1.BackColor = value; }
}
public Color TextBoxFontBackgroundColor
{
get { return customTextBox1.BackColor; }
set { customTextBox1.BackColor = value; }
}
So as you can imagine since there are quite a lot of them that need to be changed the lines just pile up.
In addition, would it be a better practice to just return the control and just work on that instead on the other form or do get/set methods considered a better practice ?
Thanks in advance.
If I understand you correctly - the problem is not the "class" but the "file". So you can simply split the class into two files (just like Visual Studio does with the InitializeComponent method) using Partial Classes.
Make sure the namespace is the same (If you create the file in a sub-folder you'll get a nested namespace. Simply change it.) Also, make sure your class begins with public partial class in both files. And don't have the same property declared in both classes.
Step by step instructions:
Right-click on your project in "Solution Explorer". Click "Add". Click "New Item". Click "class". Change class Class1 to public partial class Form1 : Form. Add using System.Windows.Forms; at the top of your file. Add your properties.
You can use either C# Regions to make a large code file manageable or you can use Partial Classes to split a large code file into multiple manageable files.
You could use a different kind of function that allows for Page.FindControl("controlNameHere"), and cast it in the right light. This is more for ASP.NET pages, not for Windows form, but you could find the same resolution here Find control by name from Windows Forms controls. This way you could pull the control name and manipulate without ever having to return anything.