Who moved my constructor?

Source: Internet
Author: User

Who moved my constructor?

-- Caused by dbnull ......

In total, dbnull has only one instance-dbnull. value. We cannot use the new dbnull () method to create a new dbnull instance. This is because the constructor of dbnull is private, probably as follows.

 

Public sealed class dbnull
{
Public static readonly dbnull value = new dbnull ();
Private dbnull ()
{
}
}

 

A typical single-instance mode, so that the = comparison between two non-null dbnull object instances will definitely return true? Looks like ...... It seems that ...... Indeed, because this object only has one instance, and their references must be equal.

Slow down. before coming to this conclusion, let's take a look at the code.

 

Using system;
Using system. Collections. Generic;
Using system. text;
Using system. xml. serialization;
Using system. IO;

Namespace consoleapplication2008
{
Public class Program
{

Public class testclass
{
[Xmlelement ()]
Public dbnull myvalue = dbnull. value;
}

Static void main (string [] ARGs)
{
Testclass V1 = new testclass ();

Xmlserializer xs = new xmlserializer (typeof (testclass ));
Memorystream MS = new memorystream ();
Xs. serialized (MS, V1 );
// String xml = encoding. utf8.getstring (Ms. getbuffer ());
// Console. writeline (XML); // The two rows can be

Ms. Seek (0, seekorigin. Begin );
Testclass v2 = Xs. deserialize (MS) as testclass;

Console. writeline (v1.myvalue = v2.myvalue? "Match": "unmatch ");

Console. readkey ();
}
}
}

 

There is nothing fancy, it's nothing more than XML serialization, and then deserialization. Run it once to see ...... Oh, why? How is the result unmatch? Can dbnull objects have two different instances? This is inconsistent with its statement! Its constructor is private and should not be called by any other object except itself ......
Sort out the ideas. What happened to the testclass object during deserialization? Of course, it is to call the testclass constructor to generate an instance. What then? Call the constructor of the type of each public member (Attribute and member variable) and assign the instance to the corresponding member ...... Why? Wait, the dbnull constructor is private. To obtain an instance, you must use dbnull. value. the. NET Framework cannot be smart enough to automatically use dbnull. value? In this case, how does dbnull be deserialized from an instance? How can a private constructor be called?

Let's take another example:

 

Using system;
Using system. Collections. Generic;
Using system. text;
Using system. xml. serialization;
Using system. IO;

Namespace consoleapplication2008
{
Public class Program
{
Public sealed class singletoneclass
{
Private Static int I = 0;
Public static readonly singletoneclass value = new singletoneclass ();

Private singletoneclass ()
{
Console. writeline ("singletoneclass is instantiated at {0}", ++ I );
}
}

Public class testclass
{
[Xmlelement ()]
Public singletoneclass myvalue = singletoneclass. value;
}

Static void main (string [] ARGs)
{
Console. writeline ("construct testclass .");
Testclass V1 = new testclass ();

Xmlserializer xs = new xmlserializer (typeof (testclass ));
Memorystream MS = new memorystream ();
Console. writeline ("V1 serialization .");
Xs. serialized (MS, V1 );

Ms. Seek (0, seekorigin. Begin );
Console. writeline ("deserializing V2 .");
Testclass v2 = Xs. deserialize (MS) as testclass;

Console. writeline (v1.myvalue = v2.myvalue? "Match": "unmatch ");

Console. readkey ();
}
}
}

 

Oh ~ The running result is as follows:

 

Construct testclass.
Singletoneclass is instantiated 1st times
V1 serialization.
Deserializing V2.
Singletoneclass is instantiated 2nd times
Unmatch

 

The singletoneclass 1st instantiation is easy to understand. It is caused by its own static read-only member value. What is the second reason? You can only call this function during deserialization, that is, ". NET Framework can call our private constructor ". Then the problem arises. I expect that only one instance object now has two instances. In this case, the result of the = Operator judgment will certainly be false, if a large number:

If (V = dbnull. value)
{
}

This code, and you have performed XML serialization/deserialization on this object, it is clear that this Code cannot work as we expected. What should I do?

If it is a custom object like singletoneclass, you can also solve the problem by using the = Operator:

 

Public sealed class singletoneclass
{
Private Static int I = 0;
Public static readonly singletoneclass value = new singletoneclass ();

Private singletoneclass ()
{
Console. writeline ("singletoneclass is instantiated at {0}", ++ I );
}

Public override bool equals (Object OBJ)
{
If (OBJ = NULL | obj. GetType () = This. GetType ())
Return true;
Else
Return false;
}

Public static bool operator = (singletoneclass A, singletoneclass B)
{
// If both are null, or both are same instance, return true.
If (system. Object. referenceequals (a, B ))
Return true;

Return A. Equals (B );
}

Public static bool Operator! = (Singletoneclass A, singletoneclass B)
{
Return! (A = B );
}
}

 

Although this operation violates the intention of the = Operator, it is also a helpless solution. You cannot refuse the. NET Framework to call your private constructor? In that case, how does deserialization work? But how can dbnull be solved? We cannot achieve our goal by modifying the. NET Framework itself? (Or let Microsoft release patches? Is this a bug ?) Which viewer can help me answer this question?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.