Create a custom setter using attributes

In the classes whose instances I save using the database of objects, I have to do this:

private string _name; public string Name { get { return this._name; } set { _name = value; this.Save(); } } 

whereas I would rather print this:

 [PersistedProperty(Name)] private string _name; 

where the PersistedProperty attributes generate the Getter and Setter in the same way as the default [Property ()] attribute, except that I want to add a line of code to the generated Setter.

Is there a way to create an attribute that does this? Hope that works with Intellisense.

How does the default attribute [Property ()] even do this? If I saw the code, I could transform it ...

Note: I actually do this in Boo, but I thought I would give C # code, as more and more people can answer this, however, if there is a specific Boo solution, I'm all ears!

Update:

My goal was just to cut down on typing and get in the way. Turns out the easiest way to do this was with a script that generates partial classes based on the markup in my classes.

The self-generating source code from markup (in tandem with partial classes) is simple and actually looks like a very promising way to get around some problems that we usually try to solve with the help of inheritance and general types.

+4
source share
2 answers

This requires aspect-oriented programming . Although it is not supported directly in .NET, this can be done using third-party tools such as PostSharp .

For intellisense to work, this must be done in the library, as the (final) compiled code will be deployed to a fully-functional getter / setter.

+1
source

Not easy to implement using IMO attributes. Perhaps you could use a different approach, such as an extension method:

 // Extension method that allows updating a property // and calling .Save() in a single line of code. public static class ISaveableExtensions { public static void UpdateAndSave<T>( this ISaveable instance, Expression<Func<T>> propertyExpression, T newValue) { // Gets the property name string propertyName = ((MemberExpression)propertyExpression.Body).Member.Name; // Updates its value PropertyInfo prop = instance.GetType().GetProperty(propertyName); prop.SetValue(instance, newValue, null); // Now call Save instance.Save(); } } ... // Some interface that implements the Save method public interface ISaveable { void Save(); } ... // Test class public class Foo : ISaveable { public string Property { get; set; } public void Save() { // Some stuff here Console.WriteLine("Saving"); } public override string ToString() { return this.Property; } } ... public class Program { private static void Main(string[] args) { Foo d = new Foo(); // Updates the property with a new value, and automatically call Save d.UpdateAndSave(() => d.Property, "newValue"); Console.WriteLine(d); Console.ReadKey(); } } 

This is a safe type, autocomplete, but it requires more code than just that. Save() on all setters, so not sure if I will actually use it ...

+1
source