索引器是属性的扩展版本吗?
答案 0 :(得分:2)
索引器允许对类或结构的实例进行索引,就像数组一样。索引器类似于属性,除了它们的访问器接受参数。
class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
// Define the indexer, which will allow client code
// to use [] notation on the class instance itself.
// (See line 2 of code in Main below.)
public T this[int i]
{
get
{
// This indexer is very simple, and just returns or sets
// the corresponding element from the internal array.
return arr[i];
}
set
{
arr[i] = value;
}
}
}
// This class shows how client code uses the indexer.
class Program
{
static void Main(string[] args)
{
// Declare an instance of the SampleCollection type.
SampleCollection<string> stringCollection = new SampleCollection<string>();
// Use [] notation on the type.
stringCollection[0] = "Hello, World";
System.Console.WriteLine(stringCollection[0]);
}
}
答案 1 :(得分:1)
这取决于观点,真的。
就C#而言,它们是两个正交的概念。类可以具有零个或多个属性,并且它也可以具有零个或多个索引器。属性按名称区分,索引器按其参数类型重载(类似于方法)。它们的相似之处在于它们可以有一个gettor,一个settor或两者,并且在那个赋值运算符(包括复杂的运算符,如+=
)知道如何处理它们。
从CLS(和VB)的角度来看,没有索引器这样的东西。只有属性,其中一些是索引的,而另一些则不是。索引属性是您必须提供除接收器本身之外的其他值以读取值的属性,以及用于写入值的接收器和新值 - 附加值是索引。还有“默认属性”的概念 - 只有一组属性(所有属性具有相同名称,但索引类型不同)可以是默认属性。
从CLR的角度来看,属性本身只是一个带有类型和一堆与之关联的方法的名称;它本身并没有任何意义。它只显示在查找该名称属性的访问器时查找方法的位置。没有默认属性的概念。
现在要调和这三件事......
通过CLS约定,普通属性在CLR级别由与具有相应签名的方法相关联的属性表示,一个用于getter,一个用于setter。对于Foo
类型的属性T
,它们将是:
T get_Foo();
void set_Foo(T);
对于索引类型为I1
,I2
,...:
T get_Foo(I1, I2, ...);
void set_Foo(I1, I2, ..., T);
要表示默认属性,DefaultMemberAttribute
用于指定该属性的名称。
C#通过将索引器表示为索引属性来协调其视图与CLS的视图。默认情况下,它对所有此类属性使用名称Item
,但您可以使用IndexerNameAttribute
强制它以不同方式命名属性。它还将使用该属性的索引器在类上粘贴DefaultMemberAttribute
,因此它被视为VB中的默认属性(以及其他显示索引属性的符合CLS的语言)。
当使用其他语言编写的类时,C#会查找DefaultMemberAttribute
。如果它存在,那么它引用的索引属性在C#中显示为该类的索引器。非默认的索引属性只能通过直接调用其访问器方法(get_Foo
和set_Foo
)从C#访问 - 尽管这将在C#4中针对COM导入的接口进行更改。
答案 2 :(得分:0)
索引器是第二层语法糖。使用属性,get和set将转换为方法调用,这些方法以get_
/ set_
为前缀。在索引器的情况下,索引器转换为方法Item()。任何索引器参数都是方法的第一个参数。此外,get_
/ set_
是方法的前缀。
对于喜欢这些例子的人:
string foo;
public string Foo {
get {
return foo;
}
set {
foo = value;
}
}
// becomes
string foo;
public string get_Foo() {
return foo;
}
public void set_Foo(string value) {
foo = value;
}
在这里,索引器会发生什么:
string[] backingFoo;
public string this[int index] {
get {
return backingFoo[index];
}
set {
backingFoo[index] = value;
}
}
// becomes
string[] backingFoo;
public string get_Foo(int index) {
return backingFoo[index];
}
public void set_Foo(int index, string value) {
backingFoo[index] = value;
}