1

在我的项目中,我有一个类Area,如下所示。属性“ CodArea”我想放置一个自定义属性,例如[NaoSelecionarAttr(true)]. 这工作正常,但是当我创建该类的一个实例时,我无法获得此自定义属性。像这样的东西:

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

2 回答 2

2

您的代码存在一些问题。

代码中的第一个问题是您正在调用默认构造函数 on Area,该构造函数初始化_codArea为 null。然后您尝试调用它,但正如预期的那样GetType,它失败了。NullReferenceException

第二个问题是你想要一个类的属性的属性。所以你必须检查(或反映)类,而不是属性。您会看到,当您编写areaPoco.CodArea...编译器时,会将其解析为get表达式的结果,在本例中为 field _codArea。通过调用GetType()on _codArea,您检索的是一个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”前缀。

  • 我建议您使用“Selecionar”,而不是 NaoSelecionar,这是一个负面属性。交易是您可以很容易地将否定句与其对应的肯定句混淆。一个月后你会问,“好吧,参数是假的,我应该选择还是不选择这个属性?”。False 通常意味着 NOT,因此,您的默认解释是在属性为 false 时不选择某些内容。

  • 您的默认构造函数正在将属性初始化为null. 正如我上面所描述的,这可能会导致错误。将其初始化为默认值 ( string.Empty),或者删除默认构造函数并仅使用需要用户为字符串提供值的构造函数。并验证这些参数——用户可能会再次null向字符串提供 a 。(一个对象在第一次构造时应该是有效的)

  • 最后一个提示。您的NaoSelecionar属性获取一个布尔参数。最后一个项目符号正是关于这一点 - 您可能会混淆属性的真实属性是否意味着“não”或“sim”。那么,为什么不简单地删除参数然后使用负参数呢?无需将truefalse传递给NaoSelecionar,因为您需要做的就是遍历您的类并查找哪些属性应用了此属性。

于 2012-06-14T16:38:36.900 回答
0

你为什么用areaPoco.CodArea.GetType()?我认为你应该使用areaPoco.GetType(). 因为您的自定义属性属于 Area 类,而不是字符串。

于 2012-06-14T16:26:42.920 回答