使用属性生成自定义setter

时间:2012-08-08 16:21:58

标签: c# .net attributes boo automatic-properties

在我使用对象数据库持久化的实例中,我不得不这样做:

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

而我更愿意输入这个:

[PersistedProperty(Name)]
private string _name;

其中PersistedProperty属性生成一个Getter和Setter,就像默认的[Property()]属性一样,除了我想在生成的Setter中添加一行代码。

有没有办法可以创建一个属性呢?希望,它适用于Intellisense。

默认的[Property()]属性是如何做的呢?如果我看到代码,我可以嫁接......

注意:我实际上是在Boo中执行此操作,但我认为我会提供c#代码,因为更多人可能愿意回答这个问题,但是,如果有一个Boo特定的解决方案,我会全力以赴!

更新

我的目标只是减少打字和杂乱。事实证明,最简单的方法是使用一个脚本,根据我的类中的标记生成部分类。

从标记(与部分类一起)自动生成源代码很容易,实际上看起来像是一种非常有前途的方法来解决我们通常尝试用继承和泛型类型解决的一些问题。

2 个答案:

答案 0 :(得分:1)

这需要aspect oriented programming。虽然在.NET中不直接支持,但可以通过第三方工具完成,例如PostSharp

然而,要使intellisense工作,必须在库中完成,因为(最终)编译的代码将展开到完整的属性getter / setter中。

答案 1 :(得分:1)

使用IMO属性不易实现。 也许你可以使用另一种方法,例如扩展方法:

// 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();
    }
}

它是类型安全的,自动完成友好的,但它需要的代码不仅仅是。Save()在所有setter中,所以不确定我会实际使用它...