C# 如何使用属性减少属性中的样板文件?

C# 如何使用属性减少属性中的样板文件?,c#,.net,mono,attributes,C#,.net,Mono,Attributes,我正在使用Sqlite和属性,代码中的属性如下所示: const string FooKey = "foo"; ... string m_foo; [DatabaseColumn (FooKey)] public string Foo { get { return m_foo; } set { if (m_foo == value) return; m_foo = value; OnFooChanged

我正在使用Sqlite和属性,代码中的属性如下所示:

const string FooKey = "foo";

...

string m_foo;
[DatabaseColumn (FooKey)]
public string Foo {
    get { return m_foo; }
    set {
        if (m_foo == value)
            return;

        m_foo = value;
        OnFooChanged (); // Calls the event FooChanged after a null check
        Update (FooKey, Foo); // Updates the field in the database
    }
}
const string BarKey = "bar";

...

bool m_bar;
[DatabaseColumn (BarKey)]
public bool Bar {
    get { return m_bar; }
    set {
        if (m_bar == value)
            return;

        m_bar = value;
        OnBarChanged (); // Calls the event BarChanged after a null check
        Update (BarKey, Bar); // Updates the field in the database
    }
}
这对于与表中的列对应的每个属性都是相同的,唯一的更改是名称和类型。也就是说,可能有其他类似的财产:

const string FooKey = "foo";

...

string m_foo;
[DatabaseColumn (FooKey)]
public string Foo {
    get { return m_foo; }
    set {
        if (m_foo == value)
            return;

        m_foo = value;
        OnFooChanged (); // Calls the event FooChanged after a null check
        Update (FooKey, Foo); // Updates the field in the database
    }
}
const string BarKey = "bar";

...

bool m_bar;
[DatabaseColumn (BarKey)]
public bool Bar {
    get { return m_bar; }
    set {
        if (m_bar == value)
            return;

        m_bar = value;
        OnBarChanged (); // Calls the event BarChanged after a null check
        Update (BarKey, Bar); // Updates the field in the database
    }
}

现在,我只使用DatabaseColumn属性来标识哪些字段对应于表中的列,这样我就可以更容易地将整行插入数据库。有没有办法让DatabaseColumn承担更多的责任,减少代码中的样板文件?

从以下几点开始:

private void SetField<T>(
    ref T field, T value,
    string key, EventHandler handler)
{
    if(EqualityComparer<T>.Default
        .Equals(field, value)) return;
    field = value;
    if(handler!=null) handler(this, EventArgs.Empty);
    if(key!=null) Update(key,value);
}
public int Foo {
    get { return foo; }
    set { SetField(ref foo, value, FooKey, FooChanged); }
}
private void设置字段(
参考T字段,T值,
字符串键,EventHandler)
{
如果(EqualityComparer.Default
.等于(字段、值))返回;
字段=值;
if(handler!=null)handler(this,EventArgs.Empty);
如果(key!=null)更新(key,value);
}
公共int-Foo{
获取{return foo;}
set{SetField(ref foo,value,FooKey,FooChanged);}
}

使用属性的问题;这就引入了相对较慢的反射。如果可能的话,我会尽量避免。

IMHO在属性更新后立即更新数据库不是一个好主意。。。看看现有的ORM框架,没有一个是这样工作的,所以可能有很好的理由(在我脑海中,我可以想到2:效率和数据完整性/一致性)@Thomas:谢谢,我会四处看看。我以前没有做过任何ORM——也许已经有一个框架可以满足我的需要。编写ORM很难,所以除非您有非常特殊的需求,否则我建议您使用现有的ORM(Entity Framework非常好,NHibernate也被广泛使用,但IMO的难度要大得多)@Thomas:看起来Mono上没有实体框架()。不过,NHibernate看起来很有前途。谢谢,这很有效。我必须养成使用这些通用方法的习惯。