Metodo KeyedCollection.ChangeItemKey
Assembly: mscorlib (in mscorlib.dll)
| Tipo di eccezione | Condizione |
|---|---|
| item è riferimento null (Nothing in Visual Basic). -oppure- key è riferimento null (Nothing in Visual Basic). | |
| Impossibile trovare item. -oppure- key esiste già nella classe KeyedCollection. |
Questo metodo non modifica la chiave incorporata nel parametro item ma sostituisce semplicemente la chiave salvata nel dizionario di ricerca. Di conseguenza, se il parametro newKey è diverso dalla chiave incorporata nel parametro item, non è possibile accedere al parametro item utilizzando la chiave restituita dalla classe GetKeyForItem.
Questo metodo non ha alcun effetto se la classe KeyedCollection non dispone di un dizionario di ricerca.
È necessario che tutte le chiavi incluse in un oggetto KeyedCollection siano univoche. Una chiave non può essere riferimento null (Nothing in Visual Basic).
Questo metodo costituisce un'operazione O(1).
Note per gli implementatori
Dopo la modifica di una chiave in un elemento incorporato, è necessario chiamare questo metodo per aggiornare la chiave nel dizionario di ricerca. Se la soglia di creazione del dizionario è –1, la chiamata a questo metodo non è necessaria.
Non esporre il metodo ChangeItemKey come metodo pubblico di una classe derivata. L'errato utilizzo di questo metodo risulterà nella mancata sincronizzazione del dizionario di ricerca con le chiavi dell'elemento. Ad esempio, l'impostazione della chiave su riferimento null (Nothing in Visual Basic) e la successiva impostazione su un altro valore, aggiunge più chiavi per un elemento al dizionario di ricerca. Esporre questo metodo internamente per consentire l'utilizzo di chiavi di elemento mutabili; se la chiave di un elemento viene modificata, questo metodo viene utilizzato per modificare la chiave nel dizionario di ricerca.
Nell'esempio di codice riportato di seguito viene illustrato come eseguire l'override del metodo protetto ChangeItemKey per supportare le chiavi modificabili e come eseguire l'override dei metodi protetti InsertItem, RemoveItem, ClearItems e SetItem per conservare l'integrità delle chiavi e dell'insieme.
Nell'esempio di codice vengono creati un insieme MutableKeys, che deriva da KeyedCollection, e la classe MutableKey. La classe MutableKey presenta una proprietà Key che può essere impostata. Quando alla proprietà viene assegnata una nuova chiave, il metodo di impostazione della proprietà chiama il metodo internal (Friend in Visual Basic) ChangeKey dell'insieme per verificare se la nuova chiave sarà in conflitto con un'altra chiave esistente. In tal caso, viene generata un'eccezione e il valore della proprietà non viene modificato.
Per mantenere la connessione tra un oggetto MutableKey e l'insieme MutableKeys e per evitare che un oggetto venga inserito in due insiemi, alla classe MutableKey è associato un campo internal (Friend in Visual Basic) Collection. Il campo viene gestito dai metodi protetti che forniscono il comportamento personalizzato per l'aggiunta e la rimozione di elementi dall'insieme, ad esempio il metodo InsertItem. Il campo viene impostato quando l'elemento viene aggiunto a un insieme e cancellato quando l'elemento viene rimosso.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; // This class demonstrates one way to use the ChangeItemKey // method to store objects with keys that can be changed. The // ChangeItemKey method is used to keep the internal lookup // Dictionary in sync with the keys of the stored objects. // // MutableKeys stores MutableKey objects, which have an Integer // Key property that can be set. Therefore, MutableKeys inherits // KeyedCollection(Of Integer, MutableKey). // public class MutableKeys : KeyedCollection<int, MutableKey> { // This parameterless constructor delegates to the base class // constructor that specifies a dictionary threshold. A // threshold of 0 means the internal Dictionary is created // the first time an object is added. // public MutableKeys() : base(null, 0) {} protected override int GetKeyForItem(MutableKey item) { // The key is MutableKey.Key. return item.Key; } protected override void InsertItem(int index, MutableKey newItem) { if (newItem.Collection != null) throw new ArgumentException("The item already belongs to a collection."); base.InsertItem(index, newItem); newItem.Collection = this; } protected override void SetItem(int index, MutableKey newItem) { MutableKey replaced = Items[index]; if (newItem.Collection != null) throw new ArgumentException("The item already belongs to a collection."); base.SetItem(index, newItem); newItem.Collection = this; replaced.Collection = null; } protected override void RemoveItem(int index) { MutableKey removedItem = Items[index]; base.RemoveItem(index); removedItem.Collection = null; } protected override void ClearItems() { foreach( MutableKey mk in Items ) { mk.Collection = null; } base.ClearItems(); } internal void ChangeKey(MutableKey item, int newKey) { base.ChangeItemKey(item, newKey); } public void Dump() { Console.WriteLine("\nDUMP:"); if (Dictionary == null) { Console.WriteLine(" The dictionary has not been created."); } else { Console.WriteLine(" Dictionary entries"); Console.WriteLine(" ------------------"); foreach( KeyValuePair<int, MutableKey> kvp in Dictionary ) { Console.WriteLine(" {0} : {1}", kvp.Key, kvp.Value); } } Console.WriteLine("\n List of items"); Console.WriteLine(" -------------"); foreach( MutableKey mk in Items ) { Console.WriteLine(" {0}", mk); } } } public class Demo { public static void Main() { MutableKeys mkeys = new MutableKeys(); // The Add method is inherited from Collection. // mkeys.Add(new MutableKey(110072674, "Widget")); mkeys.Add(new MutableKey(110072675, "Sprocket")); mkeys.Dump(); Console.WriteLine("\nCreate and insert a new item:"); MutableKey test = new MutableKey(110072684, "Gear"); mkeys.Insert(1, test); mkeys.Dump(); try { Console.WriteLine("\nTry to insert the item again:"); mkeys.Insert(1, test); } catch(ArgumentException ex) { Console.WriteLine("Error: {0}", ex.Message); } Console.WriteLine("\nChange the Key property of the item:"); test.Key = 100000072; mkeys.Dump(); try { Console.WriteLine("\nTry to set the Key property to an existing key:"); test.Key = 110072674; } catch(ArgumentException ex) { Console.WriteLine("Error: {0}", ex.Message); } mkeys.Dump(); } private static void Display(MutableKeys order) { Console.WriteLine(); foreach( MutableKey item in order ) { Console.WriteLine(item); } } } // This class has a key that can be changed. // public class MutableKey { public MutableKey(int newKey, string newValue) { _key = newKey; Value = newValue; } //New public string Value; internal MutableKeys Collection; private int _key; public int Key { get { return _key; } set { if (Collection != null) { Collection.ChangeKey(this, value); } _key = value; } } public override string ToString() { return String.Format("{0,9} {1}", _key, Value); } } /* This code example produces the following output: DUMP: Dictionary entries ------------------ 110072674 : 110072674 Widget 110072675 : 110072675 Sprocket List of items ------------- 110072674 Widget 110072675 Sprocket Create and insert a new item: DUMP: Dictionary entries ------------------ 110072674 : 110072674 Widget 110072675 : 110072675 Sprocket 110072684 : 110072684 Gear List of items ------------- 110072674 Widget 110072684 Gear 110072675 Sprocket Try to insert the item again: Error: The item already belongs to a collection. Change the Key property of the item: DUMP: Dictionary entries ------------------ 110072674 : 110072674 Widget 110072675 : 110072675 Sprocket 100000072 : 100000072 Gear List of items ------------- 110072674 Widget 100000072 Gear 110072675 Sprocket Try to set the Key property to an existing key: Error: An item with the same key has already been added. DUMP: Dictionary entries ------------------ 110072674 : 110072674 Widget 110072675 : 110072675 Sprocket 100000072 : 100000072 Gear List of items ------------- 110072674 Widget 100000072 Gear 110072675 Sprocket */
Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile per Pocket PC, Windows Mobile per Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema.