비고
커뮤니티 관심 그룹은 이제 Yammer에서 Microsoft Viva Engage로 이동했습니다. Viva Engage 커뮤니티에 가입하고 최신 토론에 참여하려면 Finance and Operations Viva Engage Community 양식에 대한 요청 액세스 권한을 작성하고 참여하려는 커뮤니티를 선택합니다.
이 문서에서는 X++의 특성 사용에 대해 설명합니다.
특성은 SysAttribute 클래스를 확장(상속)하는 비 추상 클래스입니다. 특성은 형식 및 메서드에 대한 메타데이터를 나타내거나 저장합니다. 특성은 클래스, 클래스 필드, 클래스 메서드, 인터페이스 또는 테이블에 연결할 수 있습니다.
특성은 대리자와 메서드의 처리기에 적용되어 처리기를 해당 대상에 매핑합니다.
특성 클래스 만들기
특성 클래스는 SysAttribute 클래스를 직접 확장하거나 SysAttribute 클래스의 하위 항목을 확장할 수 있습니다. SysAttribute 클래스는 추상으로 선언되어 있으므로 특성으로 사용할 수 없습니다. 다음 예제에서는 만들 수 있는 일반 특성 클래스의 선언 및 디자인을 보여줍니다.
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.
}
특성을 사용하여 클래스 데코레이팅
다음 예제에서는 이전 예제에서 제공된 PracticeAttribute 로 데코레이팅된 클래스 및 메서드를 보여 주었습니다. 특성 생성자가 매개 변수를 사용하지 않는 경우 매개 변수의 괄호는 선택 사항입니다. 특성 장식에는 괄호가 없을 [AnotherAttribute] 수 있습니다.
[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.
}
접미사가 있는 경우 특성 이름의 접미사를 생략할 수 있습니다 Attribute. 예를 들어 앞의 예제에서 대신 [Practice] 사용할 [PracticeAttribute] 수 있습니다.
특성 생성자
특성 클래스가 클래스를 데코레이팅하는 데 사용될 때마다 해당 생성자가 매개 변수를 사용하도록 설정하여 맞춤형 메타데이터를 저장할 수 있습니다. 생성자에 대한 매개 변수는 int,enum 또는 str와 같은 기본 형식의 리터럴이어야 합니다. 컴파일러는 특성 클래스의 인스턴스를 생성하지 않습니다. 특성 클래스의 이름과 해당 생성자의 리터럴 값을 저장합니다. 따라서 특성 생성자의 논리가 예외를 throw하는 경우 특성을 사용하여 클래스를 데코레이팅하여 예외를 찾을 수 없습니다. 이 예외는 나중에 프로세스에서 클래스가 데코레이팅된 특성을 확인하기 위해 클래스를 볼 때 찾을 수 있습니다. 특성이 생성되는 경우입니다.
명명 규칙
모든 특성 클래스에는 이름에 접미사 특성 이 있습니다. 특성 접미사는 권장하는 이름 규칙이지만 시스템 요구 사항은 아닙니다. 애플리케이션 탐색기에서 클래스를 선택하고 속성 창에서 Extends 속성을 검토하여 클래스가 SysAttribute에서 직접 확장되는지 여부를 확인할 수 있습니다.
SysObsoleteAttribute
시스템은 SysObsoleteAttribute 클래스를 비롯한 여러 특성을 제공합니다. SysObsoleteAttribute 클래스의 한 가지 사용은 소스 코드에서 특정 메서드가 호출되는 경우 컴파일이 실패하도록 컴파일러에 알리는 것입니다. 컴파일러는 컴파일을 거부하고 이 특성 사용에 저장된 특정 메시지를 표시합니다. SysObsoleteAttribute 클래스를 사용하여 컴파일러에 오류 대신 경고 메시지를 발급하도록 알릴 수도 있습니다.
SysObsoleteAttribute 코드 예제
[SysObsoleteAttribute("The Automobile class might have faster performance.", false)]
class Bicycle
{
// Members of the Bicycle class go here.
}
메타데이터 리플렉션
리플렉션을 사용하여 클래스에 연결된 특성 메타데이터를 찾습니다. 특성 리플렉션에 사용할 클래스는 다음과 같습니다.
- DictClass 클래스 – 클래스 및 인터페이스의 경우
- DictMethod 클래스 – 클래스, 인터페이스 또는 테이블의 메서드입니다.
이전 리플렉션 클래스에서 특성 메타데이터를 반영하는 메서드는 다음과 같습니다.
- getAllAttributes 메서드
- getAttribute 메서드
- getAttributedClasses 메서드
- getAttributes 메서드
비고
X++ 코드의 특정 특성으로 표시된 모든 메서드 또는 클래스를 나열하는 메커니즘은 없습니다. 그러나 X++ 컴파일러가 이 정보를 상호 참조 데이터베이스에 기록하기 때문에 여기에서 정보를 채굴할 수 있습니다.
메타데이터 리플렉션 코드 예제
DictMethod 클래스를 사용하여 메서드에 장식된 특성의 메타데이터 값을 찾습니다. 다음 코드 예제에서는 SysEntryPointAttribute 클래스를 특성으로 사용합니다. 메서드 이름 및 메서드를 포함하는 클래스의 이름에 대한 매개 변수 값을 허용합니다. parmChecked 메서드는 SysEntryPointAttribute 클래스에만 적용되며 기본 클래스 SysAttribute에서 상속되지 않습니다. 각 특성 클래스는 메타데이터에 대한 고유한 메서드 이름을 가질 수 있습니다.
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");
}
**************/