2012-06-14 37 views
1

在我的項目中,我有一個名爲Area的類,如下所示。 財產「CodArea」我想要把一個自定義屬性,如[NaoSelecionarAttr(true)]。 這工作正常,但是當我創建一個類的實例時,我無法獲得此自定義屬性。類似這樣的:在我的C#POCO類上使用自定義屬性

Area areaPoco = new Area(); 
areaPoco.CodArea.GetType().GetCustomAttributes(typeof(NaoSelecionarAttr),true).ToList(); 

[Serializable] 
public class Area 
{ 
    #region Private Members  
    private decimal _numChave; 
    private string _codArea; 

    public Area() 
    { 
     _numChave = 0; 
     _codArea = null; 
    } 

    public Area(decimal pNumChave,  string pCodArea) 
    { 
     NumChave = pNumChave; 
     CodArea = pCodArea; 
    } 
    public virtual decimal NumChave 
    { get { return _numChave;} 
     set { _numChave = value;} 
    } 

    [NaoSelecionarAttr(true)] 
    public virtual string CodArea 
    { 
      get { return _codArea; } 
      set { _codArea = value;} 
    } 
} 

public class NaoSelecionarAttr : Attribute 
{ 
    public bool NaoSelecionar { get; set; } 
    public NaoSelecionarAttr(bool pSim) { this.NaoSelecionar = pSim; } 
} 
} 
+0

這不會編譯:'areaPoco.CodArea..GetCustomAttributes()'。你有沒有嘗試過編譯的東西? –

+0

我在這裏寫錯了。我的代碼是複製。 – Fabio

+0

請更新您的代碼法比奧,以便我們知道您在嘗試什麼。 –

回答

2

您的代碼存在一些問題。

代碼中的第一個問題是您正在調用Area的默認構造函數,該函數將_codArea初始化爲null。然後您嘗試撥打GetType,如預期的那樣NullReferenceException失敗。

第二個問題是你想要一個類的屬性屬性。所以你必須檢查(或反映)班級,而不是財產。您會看到,當您編寫areaPoco.CodArea...時,編譯器會將其解析爲您的get表達式的結果,在此例中爲_codArea。通過在_codArea上調用GetType(),您檢索的是String類型,而不是您的Area類型。我知道這可能起初看起來很混亂,但屬性不是類型,所以你不能反思它們。

你應該做的,那麼,是:

Area areaPoco = new Area(); 
NaoSelecionarAttr attr = (NaoSelecionarAttr) (areaPoco.GetType().GetProperties().Single(p => p.Name == "CodArea").GetCustomAttributes(typeof(NaoSelecionarAttr), true).Single()); 
bool naoSelecionar = attr.NaoSelecionar; 

如果可以的話,我想給你一些提示,以及:

  • 你的符號來表示非默認的構造函數似乎讓人想起C/C++。在參數中添加「p」前綴通常沒有很好的理由。

  • 而不是NaoSelecionar,這是一個負面屬性,我建議你使用「Selecionar」。這個協議是,你可以很容易地將一個負面的句子與其相應的正面句子混淆起來。一個月後你會問,「好的,參數是錯誤的,所以我應該選擇或不選擇這個屬性?」。假通常意味着不是,所以,你的默認解釋不會選擇屬性爲假時的東西。

  • 您的默認構造函數正在將屬性初始化爲null。就像我上面所描述的那樣,這可能會導致錯誤。將其初始化爲默認值(string.Empty),或者刪除默認構造函數,並只使用需要用戶爲字符串提供值的那個。並且驗證這些參數 - 用戶可能會再次提供一個null到字符串。 (一個對象在第一次構建時應該是有效的)

  • 最後一個提示。您的NaoSelecionar屬性獲取布爾參數。最後一顆子彈恰恰與此相關 - 你可能會混淆是否爲你的屬性擁有一個真正的屬性意味着「não」或「sim」。那麼,你爲什麼不簡單地刪除參數,然後工作與否定參數?沒有必要通過truefalseNaoSelecionar,因爲您需要做的就是遍歷您的類並查找哪些屬性具有應用於此屬性的屬性。

+0

事實上,我不知道正確的方式來做到這一點,但我知道我想要什麼:)。例如:Area areaPoco = new Area();如果(areaPoco.CodArea.NaoSelecionar == true)做些什麼 – Fabio

+0

@Fabio,我已經添加了足夠的信息,以便您可以實現您想要的。 –

+0

感謝布魯諾,在您的幫助下,我已經達成了一個解決方案...... – Fabio

0

爲什麼使用areaPoco.CodArea.GetType()?我認爲你應該使用areaPoco.GetType()。因爲您的自定義屬性屬於Area類,而不屬於字符串。

+0

事實上,我不知道正確的方式來做到這一點,但我知道我想要什麼:)。例如:Area areaPoco = new Area();如果(areaPoco.CodArea.NaoSelecionar == true)做某事 – Fabio