Directory
- 1. Basic use
- 2. Other keyedcollection variants
- 3. Execute a non-Abstract keyedcollection.
Returned directory
1. Basic use
This type seems a little inconspicuous. In the namespace of system. Collections. objectmodel, it is added to. NET 2.0. Let's see its type hierarchy:
In fact, he is a dictionary, but the dictionary key is obtained from the value. It can be seen that there is not a dictionary <tkey, titem> Field in his execution to save data, it also supports the iequalitycomparer <tkey> object. But at the same time, its base class is of the collection <titem> type, and collection <titem> executes ilist <t>, ilist and these basic set operation interfaces, so keyedcollection <tkey, titem> the operation is similar to a list <t>. t indicates the titem type in keyedcollection <tkey, titem>. The result is that you can use the index value of the array or the dictionary key to access the keyedcollection member at the same time!
Of course, because the keyedcollection <tkey, titem> has a dictionary <tkey, titem> internally, and because it inherits from the collection <titem>, there is also a list <titem> internally, therefore, the <tkey, titem> type occupies more space than the dictionary <tkey, titem> type.
From the inheritance class given by ilspy, this class has been applied in WCF.
For example, we need to create a dictionary based on the file object (system. Io. fileinfo object). The dictionary key is the file path. In this case, the keyedcollection type can be used. Note that it is an abstract class, because it is unknown how to include the key, so you need to execute the getkeyforitem method of this abstract class. You can use keyedcollection after executing this method. (Note that in this example, the file path is case-insensitive, so you need to set the iequalitycomparer <string> parameter during execution)
Code:
// + Using system. Collections. objectmodel
// + Using system. Io
Class myfiledictionary: keyedcollection <string, fileinfo>
{
// Note that the file path is case insensitive, so you need to set iequalitycomparer <string>.
Public myfiledictionary ()
: Base (stringcomparer. ordinalignorecase)
{}
// Return the path from fileinfo as the key.
Protected override string getkeyforitem (fileinfo item)
{
Return item. fullname;
}
}
Then test the Code:
// Add data
VaR myfiledic = new myfiledictionary ();
Foreach (VAR fileinfo in driveinfo. getdrives () [0]. rootdirectory. getfiles ())
Myfiledic. Add (fileinfo );
// Obtain the value through index and key. Of course, true is output because they point to the same object.
Console. writeline (myfiledic [0] = myfiledic [myfiledic [0]. fullname]);
Returned directory
2. Other keyedcollection variants
The first is thread-safe keyedcollection execution.
Note: For thread security sets, we strongly recommend that you use the high-performance thread security set provided in the. NET 4.0 system. Collections. Concurrent namespace. Readers can refer to msdn.
In fact, after. Net 3.0, there is a thread-safe keyedcollection execution, which is included in the WCF Assembly: system. servicemodel. dll. After referencing this assembly, you can use system. collections. the synchronized keyedcollection type in the generic namespace: synchronizedkeyedcollection <K, T> type. It must be the same as the keyedcollection type and is also an abstract class.
There is also a type to be mentioned. It is the keyedbytypecollection <titem> type, which is directly inherited from the keyedcollection and can be seen from the name, the key of this type of keyedcollection is obtained from the value object type.
Therefore, only titem is retained and inherited from the keyedcollection <system. type, titem> type. For example:
Note:
In system. servicemodel. dll of Silverlight 5 (the version is 5.0.5.0 ):
The synchronizedcollection <t> type is internal. There is no synchronizedkeyedcollection <K, T> type.
Returned directory
3. Execute a non-Abstract keyedcollection.
Because keyedcollection is an abstract class, you must define a new type that inherits the keyedcollection every time you use it. Some troubles. Of course, you can write a general non-Abstract keyedcollection type for execution. Use a delegate field for conversion.
The following code:
Class mykeyedcollection <tkey, titem>: keyedcollection <tkey, titem>
{
Func <titem, tkey> _ converter;
Public mykeyedcollection (func <titem, tkey> converter, iequalitycomparer <tkey> comparer, int dictionarycreationthreshold)
: Base (comparer, dictionarycreationthreshold)
{
If (converter = NULL)
{
Throw new argumentnullexception ("converter ");
}
_ Converter = converter;
}
Public mykeyedcollection (func <titem, tkey> converter, iequalitycomparer <tkey> comparer)
: This (converter, comparer, 0)
{}
Public mykeyedcollection (func <titem, tkey> converter)
: This (converter, null, 0)
{}
Protected override tkey getkeyforitem (titem item)
{
Return _ converter (item );
}
}
For the above example of storing fileinfo, we do not need to define a new type. You can use this mykeyedcollection type, as shown in the following code:
VaR myfiledic = new mykeyedcollection <string, fileinfo> (fileinfo => fileinfo. fullname, stringcomparer. ordinalignorecase );