Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Grupos de interesse da comunidade mudaram do Yammer para o Microsoft Viva Engage. Para ingressar em uma comunidade do Viva Engage e participar das discussões mais recentes, preencha o formulário Solicitar acesso às Finanças e Operações viva engage community e escolha a comunidade que você deseja ingressar.
Este artigo descreve o uso de atributos em X++.
Um atributo é uma classe nonabstract que estende (herda de) a classe SysAttribute . Os atributos representam ou armazenam metadados sobre tipos e métodos. Você pode anexar um atributo a uma classe, um campo de classe, um método de classe, uma interface ou uma tabela.
Aplique atributos aos manipuladores de delegados e métodos para mapear os manipuladores para esses destinos.
Criando uma classe de atributo
Uma classe de atributo pode estender a classe SysAttribute diretamente ou pode estender qualquer descendente da classe SysAttribute . Você não pode usar a classe SysAttribute como um atributo porque ela é declarada abstrata. O exemplo a seguir mostra a declaração e o design de uma classe de atributo comum que você 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 decorados com o PracticeAttribute dado no exemplo anterior. Se o construtor do atributo não tiver parâmetros, os parênteses dos parâmetros serão opcionais. A decoração de atributo pode 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] no [PracticeAttribute] exemplo anterior.
Construtores de atributo
Você pode habilitar sua classe de atributo para armazenar metadados personalizados sempre que decorar uma classe, fazendo com que seu construtor use parâmetros. Os parâmetros para o construtor devem ser literais dos tipos primitivos, como int,enum oustr. O compilador não constrói uma instância da classe de atributo. Ele armazena o nome da classe de atributo, além dos valores literais para seu construtor. Portanto, se a lógica em um construtor de atributo gerar uma exceção, decorar uma classe com o atributo não causará a exceção. A exceção é encontrada posteriormente quando um processo examina uma classe para ver o atributo com o qual ela é decorada. Esse processo é quando o atributo é construído.
Convenções de nomenclatura
Todas as classes de atributo têm o atributo de sufixo em seu nome. O sufixo Attribute é a convenção de nome que a Microsoft recomenda, mas não é um requisito do sistema. Você pode determinar se uma classe se estende diretamente de SysAttribute selecionando a classe no Gerenciador de Aplicativos e revisando a propriedade Extends na janela Propriedades .
SysObsoleteAttribute
O sistema fornece vários atributos, incluindo a classe SysObsoleteAttribute . Um uso da classe SysObsoleteAttribute é notificar o compilador de que o compilador deve falhar se um método específico for chamado no código-fonte. O compilador rejeita o compilador 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
Você usa a reflexão para localizar os metadados de atributo anexados a uma classe. As classes a serem usadas para reflexão de atributo 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 atributo são os seguintes:
- Método getAllAttributes
- Método getAttribute
- Método getAttributedClasses
- Método getAttributes
Observação
Não há nenhum mecanismo para listar todos os métodos ou classes adornados com um atributo específico do código X++. No entanto, como o compilador X++ registra essas informações no banco de dados de referência cruzada, você pode extrair essas informações nela.
Exemplo de código de reflexão de metadados
Use a classe DictMethod para localizar o valor de metadados de um atributo que decora um método. O exemplo de código a seguir usa a classe SysEntryPointAttribute 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 para a classe SysEntryPointAttribute e não é herdado de 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");
}
**************/