7

在我使用对象数据库保留其实例的类中,我一直不得不这样做:

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 特定的解决方案,我会全神贯注!

更新:

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

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

4

2 回答 2

1

这需要面向方面的编程。虽然 .NET 不直接支持,但可以通过第三方工具完成,例如PostSharp

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

于 2012-08-08T16:27:28.523 回答
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()在所有的二传手中,所以不确定我是否会实际使用它......

于 2012-08-08T16:48:33.167 回答