Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Observação
Os grupos de interesse da comunidade passaram do Yammer para o Microsoft Viva Engage. Para participar de uma comunidade Viva Engage e participar das últimas discussões, preencha o formulário Solicitar acesso ao Finance and Operations Viva Engage Community e escolha a comunidade à qual deseja participar.
Este artigo descreve o uso de atributos no X++.
Um atributo é uma classe não abstrata que se estende (herda de) a classe SysAttribute . Os atributos representam ou armazenam metadados sobre tipos e métodos. Pode anexar um atributo a uma classe, um campo de classe, um método de classe, uma interface ou uma tabela.
Aplicar atributos aos handlers dos delegados e métodos para mapear os handlers para esses alvos.
Criando uma classe de atributo
Uma classe de atributo pode estender a classe SysAttribute diretamente, ou pode estender qualquer descendente da classe SysAttribute . Não podes usar a classe SysAttribute como atributo porque é declarada abstrata. O exemplo seguinte mostra a declaração e o design de uma classe de atributos ordinária que pode criar.
public class PracticeAttribute extends SysAttribute
{
// Fields in the classDeclaration.
StartEnd startEndEnum;
str reason;
// Constructor.
public void new(StartEnd _startEndEnum, str _reason)
{
startEndEnum = _startEndEnum;
reason = _reason;
}
// Other methods can go here.
}
Decorando uma classe com um atributo
O exemplo a seguir mostra uma classe e um método que são decorados com o PracticeAttribute dado no exemplo anterior. Se o construtor do atributo não usa parâmetros, os parênteses para os parâmetros são opcionais. A decoração do atributo poderia ser [AnotherAttribute] sem parênteses.
[PracticeAttribute(StartEnd::End, "Use the RegularClass class at the end.")]
public class RegularClass
{
[PracticeAttribute(Startend::Start, "Use the rehearse method at the start.")]
public int rehearse()
{
// Logic goes here.
}
// More fields and methods belong here.
}
Você pode omitir o sufixo do nome do atributo se o sufixo for Attribute. Por exemplo, você pode usar [Practice] em vez disso [PracticeAttribute] no exemplo anterior.
Construtores de atributos
Pode permitir que a sua classe de atributo armazene metadados personalizados cada vez que decora uma classe, fazendo com que o seu construtor tome parâmetros. Os parâmetros para o construtor devem ser literais dos tipos primitivos, como int,enum ou str. O compilador não constrói uma instância da classe atributo. Ele armazena o nome da classe de atributo, mais os valores literais para seu construtor. Portanto, se a lógica num construtor de atributos lançar uma exceção, decorar uma classe com o atributo não causa a exceção. A exceção é encontrada mais tarde, quando um processo analisa uma classe para ver o atributo com que está decorada. Esse processo é quando o atributo é construído.
Convenções de nomenclatura
Todas as classes de atributos têm o sufixo Attribute em seu nome. O sufixo Atributo é a convenção do nome recomendada pela Microsoft, mas não é um requisito do sistema. Você pode determinar se uma classe se estende diretamente de SysAttribute selecionando a classe no Application Explorer e examinando a propriedade Extends na janela Properties .
SysObsoleteAttribute
O sistema fornece vários atributos, incluindo a classe SysObsoleteAttribute . Um uso da classe SysObsoleteAttribute é notificar o compilador de que a compilação deve falhar se um determinado método for chamado no código-fonte. O compilador rejeita a compilação e exibe a mensagem específica armazenada neste uso do atributo. A classe SysObsoleteAttribute também pode ser usada para notificar o compilador para emitir mensagens de aviso em vez de erros.
Exemplo de código SysObsoleteAttribute
[SysObsoleteAttribute("The Automobile class might have faster performance.", false)]
class Bicycle
{
// Members of the Bicycle class go here.
}
Reflexão de metadados
Use a reflexão para localizar os metadados de atributo anexados a uma classe. As classes a serem usadas para reflexão de atributos são as seguintes:
- Classe DictClass – Para classes e interfaces.
- Classe DictMethod – Para métodos em classes, interfaces ou tabelas.
Nas classes de reflexão anteriores, os métodos para refletir sobre metadados de atributos são os seguintes:
- Método getAllAttributes
- Método getAttribute
- Método getAttributedClasses
- Método getAttributes
Observação
Não existe um mecanismo para listar todos os métodos ou classes que estejam adornados com um atributo específico do código X++. No entanto, como o compilador X++ regista esta informação na base de dados de referência cruzada, pode extrair essa informação a partir daí.
Exemplo de código de reflexão de metadados
Use a classe DictMethod para encontrar o valor dos metadados de um atributo que decora um método. O exemplo de código a seguir usa o SysEntryPointAttribute classe como o atributo. Ele aceita seus valores de parâmetro para o nome do método e para o nome da classe que contém o método. O método parmChecked é particular da classe SysEntryPointAttribute , e não é herdado da sua classe base SysAttribute. Cada classe de atributo pode ter seu próprio nome de método para seus metadados.
static public int MetadataOfSysEntryPointAttributeOnMethod
(
str _sNameOfClass,
str _sNameOfMethod
)
{
// Return Values:
// 0 == Has the attribute, its metadata value is false;
// 1 == Has the attribute, its metadata value is true;
// 2 == The method lacks the SysEntryPointAttribute.
int nReturnValue = -1,
nClassId;
boolean boolParmChecked;
DictMethod dm;
Object attributeAsObject;
SysEntryPointAttribute sepAttribute;
Global::info("Starting AttributeReflection"
+ " ::MetadataOfSysEntryPointAttributeOnMethod ....");
Global::info(strFmt
("Parameters are: _sNameOfClass = %1 , _sNameOfMethod = %2 .",
_sNameOfClass, _sNameOfMethod)
);
nClassId = Global::className2Id(_sNameOfClass);
dm = new DictMethod
(UtilElementType::ClassInstanceMethod,
nClassId,
_sNameOfMethod
);
attributeAsObject = dm.getAttribute("SysEntryPointAttribute");
if (attributeAsObject is SysEntryPointAttribute)
{
sepAttribute = attributeAsObject as SysEntryPointAttribute;
boolParmChecked = sepAttribute.parmChecked();
if (boolParmChecked)
nReturnValue = 1;
else
nReturnValue = 0;
Global::info(
strFmt("Return value is %1.",
nReturnValue)
);
}
else
{
nReturnValue = 2;
Global::error("Object is not a SysEntryPointAttribute??");
}
return nReturnValue;
}
/*** Output displayed in the Infolog.
Message (05:03:22 pm)
Starting AttributeReflection ::MetadataOfSysEntryPointAttributeOnMethod ....
Parameters are: _sNameOfClass = CustCustomerService , _sNameOfMethod = create .
Return value is 1.
***/
/**************
// Simple AOT > Jobs job to run the method.
static void AttributeReflection33Job(Args _args)
{
AttributeReflection::MetadataOfSysEntryPointAttributeOnMethod
("CustCustomerService", "create");
}
**************/