Reputation: 3506
I have two simple questions, based on the fact that I am extending an existing class...
1) I am implementing some custom properties, and I would like that whenever their values change a specific (parameterless) function be called. Of course, if there was no need to call the function I could use the traditional { get; set; }
syntax with no need for an additional variable. However, and even if the only thing I modify in the set
accessor is the call to the other function, I must declare a private variable so that I can specify the get
and set
accessors myself... Isn't there a simpler way to do this without declaring so many variables? Isn't there something like a gerenal "property change" event?
2) Since I am overriding a .NET user control, I would like to change the category under which some of the base properties appear. At the moment, and just to use the [Category("")]
syntax, I must declare those properties as new
and implement get
and set
referring to the base classe's properties. Isn't there a simple way to do this?
Upvotes: 3
Views: 264
Reputation: 11420
Maybe I'm off here but what about something like this for #1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EraseMe2
{
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.MyProperty = 100;
t.MyProperty = 500;
}
}
class Test
{
public int set(ref int prop, int val)
{
prop = val;
Console.WriteLine(String.Format("{0} changed to {1}", prop.GetType().Name, val.ToString()));
return val;
}
private int _myProperty;
public int MyProperty
{
get { return _myProperty; }
set
{
_myProperty = set(ref _myProperty, value);
}
}
}
}
Upvotes: 0
Reputation: 8885
C# doesn't support this natively, but you can go AOP via Interceptors in Windsor, which will give you a hit in runtime or use something like PostSharp to generate code for the calls to the events. PostSharp will inject the IL code after the assemblies are created, so it shouldn't give as big as performance hit as Windsor during runtime.
It is a good idea to read a bit more about AOP as well.
Upvotes: 1
Reputation: 5407
Maybe you should look into the INotifyPropertyChanged interface. Below is some example code that uses it. I use this interface to accomplish data binding in WPF. You could handle the event, discover the property that changed and act accordingly. You could even raise the event on another thread (PropertyChanged.BeginInvoke()) if you wanted the setter to be asynchronous...
using System;
using System.ComponentModel;
public class Foo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
Upvotes: 1
Reputation: 8951
1) No there isn't a property change event. If you're insistent on not creating extra variables you could go the AOP route. You should be satisfied without AOP unless there are countless properties you're dealing with, in which case you could opt for code-generation (maybe write a python/ruby script to generate code or use a common code generator)
2) I don't think you can change properties pre-runtime (in Visual Studio) without code generation.
Upvotes: 0
Reputation: 2044
If you are trying to capture events off of properties accessed without a lot of duplicated coding while maintaining a seperation of concerns then you could look into Aspect Oriented Programming techniques using frameworks such as Castle, but beware that this is a complicated topic that includes hard choices about the architecture of your application.
Upvotes: 0