When I used foreach (httpcookie cookie in request. Cookies) for the first time, I did not expect it to go wrong. The error message turned out to be"
The specified conversion is invalid .".The request. Cookie type is httpcookiecollection. How can an error be reported? Is httpcookiecollection distinctive?
Since it cannot be converted, what type of cookie is it? Let's test it with code:
Foreach (Object cookie in request. Cookies)
{
Response. Write (cookie. GetType (). tostring () + "<br> ");
}
The original cookie is changed to the system. string type. The value of the cookie variable above is the name of each cookie in request. Cookies. The following two pieces of code have the same results:
Foreach (Object cookie in request. Cookies)
{
Response. Write (cookie + "<br> ");
}
Foreach (string cookie in request. Cookies. allkeys)
{
Response. Write (cookie + "<br> ");
}
How can we enumerate request. Cookies? I don't need to talk much about indexing, as we all know.
For (INT I = 0; I <request. Cookies. Count; I ++)
{
Response. Write (request. Cookies [I]. Name + ":" + request. Cookies [I]. Value + "<br> ");
}
The problem does not exist in javase. net. cookiecollection. What is the difference between httpcookiecollection and cookiecollection? Let's compare their base classes and interfaces:
Httpcookiecollection inherits the nameobjectcollectionbase and nameobjectcollectionbase implements the icollection, ienumerable, iserializable, and ideserializationcallback interfaces.
Cookiecollection implements the icollection and ienumerable interfaces.
I think the answer should be available in nameobjectcollectionbase.
First, let's review the working principle of foreach. First, let's look at the following code:
Namespace Test
{
Class class1
{
Static void main (string [] ARGs)
{
Arraylist array = new arraylist ();
Array. Add ("");
Array. Add ("B ");
Array. Add ("C ");
Foreach (string item in array)
{
Console. writeline (item );
}
}
}
During compilation, the C # editor converts each foreach area to the following code:
Ienumerator enumerator = array. getenumerator ();
Try
{
String item;
While (enumerator. movenext ())
{
Item = (string) enumerator. Current;
Console. writeline (item );
}
}
Finally
{
Idisposable d = enumerator as idisposable;
If (D! = NULL) D. Dispose ();
}
For foreach (httpcookie cookie in request. Cookies), the conversion result should be as follows:
Ienumerator enumerator = httpcookiecollection. getenumerator ();
Try
{
Httpcookie item;
While (enumerator. movenext ())
{
Item = (httpcookie) enumerator. Current;
}
}
Finally
{
Idisposable d = enumerator as idisposable;
If (D! = NULL) D. Dispose ();
}
Because the above enumerator. Current returns the system. string type, the error "the specified conversion is invalid" will occur.
Use reflector to view the source code of nameobjectcollectionbase and you can find httpcookiecollection. getenumerator () calls getenumerator () in nameobjectcollectionbase, while getenumerator () returns an instance of nameobjectkeysenumerator in nameobjectcollectionbase, which implements ienumerator.
The above enumerator. Current is actually the current attribute of the nameobjectkeysenumerator called, and the current attribute calls the basegetkey of the nameobjectcollectionbase. My head is dizzy! To find the real cause of the problem, you can only continue. The basegetkey code is as follows:
Protected string basegetkey (INT index)
{
Nameobjectcollectionbase. nameobjectentry entry1 = (nameobjectcollectionbase. nameobjectentry) This. _ entriesarray [Index];
Return entry1.key;
}
The answer is finally found. nameobjectcollectionbase returns a member key of nameobjectentry (which is also an internal class of nameobjectcollectionbase), which is of the string type.
Although the cause of the problem is found, the reason for this design is not clear for the time being. It can only be studied later. Of course, it would be better if there are some people to solve the problem.