簡體   English   中英

如何覆蓋類中所有屬性的get和set方法?

[英]How can I override get and set methods for all properties in a class?

我有幾個類看起來像下面的那個,我需要在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
    }
}

不是直接的,只有一個編譯器沒有辦法做到這一點。 您必須生成整個二進制文件,然后使用一些外部工具對其進行后處理。

這篇文章描述了一個類似的問題; 我希望它有所幫助。

我認為你需要的是你班上的Proxy ,閱讀Proxy PatternDynamic Proxies

有多種方法可以做到這一點。 一種方法是創建一個代理類(前面提到過),但這需要代表你進行大量的重構。 另一種方式是方面。 這些完全符合您的要求(基於先決條件插入代碼...即從類繼承的所有get方法)。 我遇到了類似的問題(實際上是完全相同的問題 - 檢查方法調用的安全性),並且找不到滿足我需求的廉價/免費方面軟件。

所以,我決定在函數調用之前使用Mono-Cecil來注入代碼。

如果你感興趣(處理IL代碼有點亂)我可以發布源代碼的舊副本

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

我現在正在尋找一個答案...我最好的想法是定義你想要被驗證為泛型類的所有屬性。 例如:

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;
}

您應該提取公共代碼以分離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;
}

這可以通過間接值訪問來完成,例如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”:-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM