एक निर्माणकर्ता को बुलाए बिना WCF डिसेरिएलाइज़ेशन ऑब्जेक्ट को तुरंत कैसे करता है?


79

कुछ जादू WCF deserialization के साथ चल रहा है। यह अपने कॉन्ट्रैक्टर को कॉल किए बिना डेटा कॉन्ट्रैक्ट के प्रकार का एक उदाहरण तुरंत कैसे देता है?

उदाहरण के लिए, इस डेटा अनुबंध पर विचार करें:

[DataContract]
public sealed class CreateMe
{
   [DataMember] private readonly string _name;
   [DataMember] private readonly int _age;
   private readonly bool _wasConstructorCalled;

   public CreateMe()
   {
      _wasConstructorCalled = true;
   }

   // ... other members here
}

जब DataContractSerializerआपके माध्यम से इस ऑब्जेक्ट का एक उदाहरण प्राप्त होता है, तो आप देखेंगे कि फ़ील्ड _wasConstructorCalledहै false

तो, WCF यह कैसे करता है? क्या यह एक ऐसी तकनीक है जिसका उपयोग दूसरे भी कर सकते हैं, या क्या यह हमसे दूर है?

जवाबों:


102

FormatterServices.GetUninitializedObject()एक निर्माता को बुलाए बिना एक उदाहरण बनाएगा। मैंने इस वर्ग को रिफ्लेक्टर का उपयोग करके और कुछ मूल .नेट अनुक्रमिक कक्षाओं के माध्यम से खुदाई करके पाया ।

मैंने नीचे दिए गए नमूना कोड का उपयोग करके इसका परीक्षण किया और ऐसा लगता है कि यह बहुत अच्छा काम करता है:

using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace NoConstructorThingy
{
    class Program
    {
        static void Main()
        {
            // does not call ctor
            var myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass));

            Console.WriteLine(myClass.One); // writes "0", constructor not called
            Console.WriteLine(myClass.Two); // writes "0", field initializer not called
        }
    }

    public class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass ctor called.");
            One = 1;
        }

        public int One { get; private set; }
        public readonly int Two = 2;
    }
}

http://d3j5vwomefv46c.cloudfront.net/photos/large/687556261.png


6
ठीक है, मैंने पहले एक गलत उत्तर पोस्ट किया था (अब हटा दिया गया) इसलिए मैंने दोषी महसूस किया। एक प्रोग्रामर को चोट पहुंचाने जैसा कुछ भी नहीं है उसे कुछ शोध करने के लिए अहंकार।
जेसन जैक्सन

3
क्या अब कोई और सोच रहा है कि कैसे FormatterServices.GetUninitializedObject काम करता है, तब? प्रतिबिंब?
3

अगर मुझे इसकी एक कॉल देशी कोड में याद आती है। मैं इस परावर्तन के साथ खरगोश छेद नीचे किसी भी आगे का पालन नहीं कर सकता।
जेसन जैक्सन

6
अजीब - मैं लिनडपैड में उस कोड को चलाता हूं और मुझे आउटपुट के रूप में 0: 0 मिला है। वास्तव में है कि बनाता है मुझे करने के लिए भावना के बाद से क्षेत्र initializers AFAIK ctors में inlined कर रहे हैं
bushed

1
@ कूड़ा सही है। मैंने यहां कोड और परिणाम के साथ स्क्रीनशॉट पोस्ट किया है । पहले मुझे लगा कि यह .NET फ्रेमवर्क संस्करणों में अंतर हो सकता है (क्योंकि उत्तर पहले से ही 4 साल पुराना है) लेकिन मैंने 2.0 और 4.0 के लिए जांच की और वे दोनों 0 और 0 को कंसोल पर लिखते हैं। जेसन जैक्सन, क्या आप इन निष्कर्षों को प्रतिबिंबित करने के लिए अपनी पोस्ट अपडेट कर सकते हैं?
ओलिवर

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.