如何覆盖类中所有属性的get和set方法?

时间:2011-01-05 07:34:41

标签: c# .net

我有几个类看起来像下面的那个,我需要在get方法和自定义set方法中做一些检查。在每个get和set方法中添加代码会使一切看起来都搞砸了。

有没有办法可以覆盖整个类中所有属性的get和set方法?

public class Test
{
    private DataRow _dr;
    public Test()
    {
        _dr = GetData();
    }

    public string Name
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
        }
    }

    public string Description
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
        }
    }

    public string DescriptionUrl
    {
        get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
        set
        {
            VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
            _dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
        }
    }


    private void VerifyAccess(string propertyname, string classname)
    {
        //some code to verify that the current user has access to update the property
        //Throw exception
    }

    private DataRow GetData()
    {
        //Some code to pull the data from the database
    }
}

6 个答案:

答案 0 :(得分:1)

不是直接的,只有一个编译器没有办法做到这一点。您必须生成整个二进制文件,然后使用一些外部工具对其进行后处理。

This post描述了一个类似的问题;我希望它有所帮助。

答案 1 :(得分:1)

我认为您需要的是您课堂上的 Proxy ,请阅读 Proxy Pattern Dynamic Proxies < / em>的

答案 2 :(得分:1)

有多种方法可以做到这一点。 一种方法是创建一个代理类(前面提到过),但这需要代表你进行大量的重构。 另一种方式是方面。这些正是您所追求的(根据先决条件插入代码,即从x继承的类中的所有get方法)。我遇到了类似的问题(实际上是完全相同的问题 - 检查方法调用的安全性),并且找不到满足我需求的廉价/免费方面软件。

所以,我决定在函数调用之前使用Mono-Cecil注入代码。

如果你感兴趣(处理IL代码有点乱)我可以发布源代码的旧副本

答案 3 :(得分:0)

您应该提取公共代码以分离get / set方法,之后您将能够向属性添加公共逻辑。顺便说一下,无论如何我都会进行这样的提取以避免代码中的复制/粘贴。

像这样的Smth:

public string Name
{
    get { return GetProperty(MethodBase.GetCurrentMethod()); }
    set
    {
        SetProperty(MethodBase.GetCurrentMethod(), value);
    }
}

private string GetProperty(MethodBase method)
{
    return _dr[method.Name.Substring(4)].ToString();
}

private void SetProperty(MethodBase method, string value)
{
    string methodName = method.Name.Substring(4);
    VerifyAccess(methodName , this.GetType().Name);
    _dr[methodName] = value;
}

答案 4 :(得分:0)

这可以通过间接价值访问来完成,例如: obj.PropA.Value = obj.PropB.Value + 1 - 您甚至可以保留强大的输入信息。它可以使用属性或直接实例化来实现。

// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;

// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
或者,也许使用诸如TT4的模板系统可能是可行的方法。

但是,不要忘记“KISS”: - )

答案 5 :(得分:0)

我希望有人能为此提供更好的答案。

我现在正在寻找答案...我最好的想法是定义你想要被验证为通用类的所有属性。例如:

public class Foo {
    public String Name { 
        get{ return _Name.value; }
        set{ _Name.value = value; }
    }
    private Proxy<String> _Name;

    static void main(String[] args) {
        Foo f = new Foo();

        //will go through the logic in Proxy.
        f.Name = "test"; 
        String s = f.Name;
    }
}
public class Proxy<T> {
    public T value { 
        get { 
            //logic here
            return _this; 
        } set {
            //logic here
            _this = value;
        } 
    }
    private T _this;
}