属性(C++ 组件扩展)
声明 属性,是成员函数的行为和访问与数据成员或数组元素。
所有运行时
可以声明特性的以下类型之一。
简单属性
默认情况下,创建一个分配属性值的 set accessor、一个检索属性值的 get 访问器 和一个私有数据成员包含属性的 set 访问器。特性块
使用此创建用户定义的获取和/或 set 访问器。该属性为读写,如果 get 和 set 访问器定义,是只读的,如果只有 get 访问器定义和只读,如果只有 set 访问器定义。您必须显式声明数据成员包含属性值。
索引属性
特性块可以使用获取和设置由一个或多个索引指定的属性值。可以创建具有用户定义的属性名或一个 默认 属性名称的索引属性。默认索引属性的名称是属性定义选件类的名称。若要声明默认属性,指定 default 关键字而不是属性名称。
您必须显式声明数据成员包含属性值。对于索引属性,数据成员通常是数组或集合。
语法
property type property_name;
property type property_name {
access-modifier type get() inheritance-modifier {property_body};
access-modifier void set(type value) inheritance-modifier {property_body};
}
property type property_name[index_list] {
access-modifier type get(index_list) inheritance-modifier {property_body};
access-modifier void set(index_list, value) inheritance-modifier {property_body};
}
property type default[index_list] {
access-modifier type get(index_list) inheritance-modifier {property_body};
access-modifier void set(index_list, value) inheritance-modifier {property_body};
}
参数
type
属性值的数据类型而属性。property_name
属性的名称。access-modifier
访问限定符。有效的限定符是 static 和 virtual。获取或设置的访问器不需要访问 virtual 限定符达成一致,但是,它们必须为 static 限定符达成一致。
inheritance-modifier
继承限定符。有效的限定符是 abstract 和 sealed。index_list
逗号分隔列表一个或多个索引。每个索引包括索引类型和可用于属性方法体的选项标识符。value
分配给设置操作的属性或检索的值在获取操作。property_body
设置或获取访问器的属性方法体。property_body 可以使用 index_list 访问基础属性数据成员,或者作为参数在用户定义过程。
Windows 运行时
备注
属性声明在所有运行时部分的适用于 Windows 运行时 元素特殊用途的属性。与其他若要共享组件属性,则应用程序必须支持以下指南。
声明属性 public 将其包含在元素的 Windows 元数据 (.winmd) 文件。
由于仅接口可由 Windows 运行时 元素显示,必须声明属性的 type 参数用作接口。然后在元素必须实现接口。
要求
编译器选项:/ZW
示例
下面的代码示例演示 IImage 接口的说明,声明 ImageSize 属性。然后该示例演示实现 IImage 接口和 ImageSize 特性的图像选件类。最后,该示例演示如何使用 ImageSize 属性。
// wrt_property1.cpp
// compile with: /ZW
using namespace Windows::Foundation;
// Interface definition
public interface class IMyImage
{
property Size ImageSize
{
Size get();
void set(Size sz);
}
};
// Implementation
ref class MyImage: IMyImage
{
protected:
Size imageSize;
public:
property Size ImageSize {
virtual Size get() { return imageSize; };
virtual void set(Size sz){ imageSize = sz; };
}
};
// Usage
int main(Array<String^>^ args) {
MyImage^ img = ref new MyImage();
img->ImageSize = Size(10,10);
uint64 byteSize = img->ImageSize.Width * img->ImageSize.Height;
wprintf(L"The total byte count is: %d\n", byteSize);
}
Output
公共语言运行时
语法
modifier property type property_name;
modifier property type property_name {
modifier void set(type);
modifier type get();
}
modifier property type property_name[index-list, value] {
modifier void set(index-list, value);
modifier type get(index-list);
modifier property type default[index];
}
参数
修饰符
在属性声明或访问。使用/修饰符 set 访问器方法。可能的值为 static 和 virtual。type
由属性表示值的类型。property_name
引发方法的参数;必须与委托的签名。index_list
逗号分隔在方括号 (编写在下方的运算符中列出一个或多个索引,指定,([])。对于每个索引,请指定可用于属性方法体的类型和可选的标识符。
备注
第一个语法示例演示一个 简单的属性,隐式声明 set 和 get 方法。编译器会自动创建一个私有字段以存储属性的值。
第二个语法示例演示 特性块,显式声明 set 和 get 方法。
第三个语法示例演示一个客户定义的 索引属性。索引属性采用参数以外将设置或检索的值之外。您必须指定属性名称。不同于一个简单的属性,必须显式定义索引属性的 set 和 get 方法,因此,您必须指定属性名称。
第四个语法示例演示一个 默认 属性,以提供对该类型的实例的类似数组的访问。关键字,default,服务仅指定默认属性。默认属性名称是定义属性类型的名称。
property 关键字只能出现在选件类、接口、值类型。属性可以具有访问功能 (只读),一个设置的函数 (只读),或者两个 (读/写)。
属性名不能与包含该托管选件类的名称。Getter 函数的返回类型与相应的 setter 函数的最后一个参数的类型相匹配。
对客户端代码中,属性具有一个普通数据成员的外观,还可以在写入或通过使用语法读取和数据成员相同。
get 和 set 方法不需要访问修饰符 virtual 达成一致。
获取的可访问性和 set 方法可能会不同。
属性方法的定义可能在选件类主体外部出现,与普通方法。
get 和 set 方法属性于 静态 修饰符达成一致。
则该 get 和 set 方法以匹配以下内容述,属性是标量的:
get 方法没有参数,并且返回类型 T。
该设置的方法具有类型 T的参数,并返回类型 空。
只有在具有相同标识符的范围中声明的标量属性。无法重载标量属性。
当属性数据成员声明时,编译器插入称为“后备存储”数据成员有时—在选件类。但是,数据成员的名称为窗体此类不能引用该源的成员,就象它包含的选件类的一个实际数据成员。使用 ildasm.exe 查看您的类型的元数据以及属性的后备存储器发现该编译器生成的名称。
不同的可访问性允许在属性的方法块的访问器。即这个 set 方法可以是公共的,并且 get 方法可以是私有的。但是,它是具有访问器方法的一个错误可以限制性较小的辅助功能相比在属性的说明。
property 是上下文相关关键字。有关更多信息,请参见上下文相关的关键字(C++ 组件扩展)。
有关属性的更多信息,请参见
要求
编译器选项:/clr
示例
下面的示例演示了属性数据成员和属性的声明和使用块。它还演示,属性访问器可以定义超出选件类。
// mcppv2_property.cpp
// compile with: /clr
using namespace System;
public ref class C {
int MyInt;
public:
// property data member
property String ^ Simple_Property;
// property block
property int Property_Block {
int get();
void set(int value) {
MyInt = value;
}
}
};
int C::Property_Block::get() {
return MyInt;
}
int main() {
C ^ MyC = gcnew C();
MyC->Simple_Property = "test";
Console::WriteLine(MyC->Simple_Property);
MyC->Property_Block = 21;
Console::WriteLine(MyC->Property_Block);
}
Output