2009-11-20 7 views

Répondre

2

Les indexeurs permettent d'indexer les instances d'une classe ou d'une structure comme des tableaux. Les indexeurs ressemblent à des propriétés sauf que leurs accesseurs prennent des paramètres.

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]); 
    } 
} 

http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

0

indexeurs sont une seconde couche de sucre syntaxique. Avec les propriétés, get et set sont transformés en appels de méthodes, ces méthodes étant préfixées par get_/set_. Dans le cas des indexeurs, les indexeurs sont transformés en la méthode Item(). Avec n'importe quel argument d'indexeur étant les premiers arguments des méthodes. En outre, get_/set_ est préfixé aux méthodes.

Pour ceux qui préfèrent des exemples:

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; 
} 

Et voici ce qui se passe avec indexeurs:

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; 
} 
1

Cela dépend du point de vue, vraiment.

En ce qui concerne C#, ce sont deux concepts orthogonaux. Une classe peut avoir zéro ou plusieurs propriétés, et peut également avoir zéro ou plusieurs indexeurs. Les propriétés sont distinguées par leurs noms, et les indexeurs sont surchargés par les types de leurs arguments (semblables aux méthodes). Ils sont similaires en ce sens qu'ils peuvent avoir un gettor, un settor, ou les deux, et dans cette affectation les opérateurs (y compris les opérateurs complexes, tels que +=) savent comment les gérer. Du point de vue de CLS (et VB), il n'existe pas d'indexeur. Il n'y a que des propriétés, et certaines d'entre elles sont indexées, alors que d'autres ne le sont pas. Une propriété indexée est celle où vous devez fournir des valeurs supplémentaires en dehors du récepteur lui-même pour lire la valeur, et le récepteur et une nouvelle valeur pour écrire la valeur - les valeurs supplémentaires sont des indices. Il y a aussi le concept d'une "propriété par défaut" - un seul groupe de propriétés (toutes avec le même nom mais différents types d'index) peut être utilisé par défaut. Du point de vue du CLR, une propriété en elle-même est juste un nom avec un type et un tas de méthodes qui y sont associées; cela n'a pas vraiment de sens en soi. Il montre juste où trouver les méthodes lors de la recherche d'accesseurs pour la propriété de ce nom. Il n'y a pas de notion de propriétés par défaut.

Maintenant, pour concilier ces trois choses ...

Par convention CLS, les propriétés simples sont représentés au niveau CLR par une propriété associée à des méthodes avec des signatures correspondantes, un pour getter et un pour setter. Pour une propriété de type FooT, ils seraient:

T get_Foo(); 
void set_Foo(T); 

Et pour une propriété indexée avec des indices de types I1, I2 ...:

T get_Foo(I1, I2, ...); 
void set_Foo(I1, I2, ..., T); 

Pour représenter une propriété par défaut, DefaultMemberAttribute est utilisé pour spécifier le nom de cette propriété. C# concilie sa vue avec celle de CLS en représentant les indexeurs en tant que propriétés indexées.Par défaut, il utilise le nom Item pour toutes ces propriétés, mais vous pouvez utiliser IndexerNameAttribute pour le forcer à nommer la propriété différemment. Il va également coller un DefaultMemberAttribute sur la classe avec l'indexeur pour cette propriété, donc il est considéré comme la propriété par défaut dans VB (et d'autres langages compatibles CLS qui montrent les propriétés indexées en tant que telles). Lorsque vous consommez des classes écrites dans d'autres langues, C# recherche DefaultMemberAttribute. Si elle est présente, la propriété indexée référencée par elle apparaît comme indexeur sur cette classe à partir de C#. Les propriétés indexées qui ne sont pas par défaut sont uniquement accessibles à partir de C# en appelant directement leurs méthodes d'accès (get_Foo et set_Foo) - bien que cela change dans C# 4 pour les interfaces importées COM.