2011-10-31 12 views
5

क्या कोई ऐसी स्थिति है जब एक ही ऑब्जेक्ट को क्रमबद्ध करने से अलग-अलग धाराएं उत्पन्न हो सकती हैं (माना जाता है कि .NET का प्रारूपण दोनों में सेरियलाइजेशन के लिए उपयोग किया जाता है)?एक ही वस्तु को क्रमबद्ध करने से विभिन्न धाराएं उत्पन्न हो सकती हैं?

यह this post से नीचे की चर्चा में आया था। दावा किया गया था कि ऐसा हो सकता है, फिर भी कोई ठोस स्पष्टीकरण नहीं दिया गया था, इसलिए मैं सोच रहा था कि क्या कोई इस मुद्दे पर कुछ प्रकाश डाल सकता है?

+0

ठीक है, ऐसा लगता है कि मैं यह साबित करना है:

ठीक है, यहाँ सबूत कोड है। ** मैं नमूना ऐप बनाने की कोशिश करूंगा। ** – Aliostad

+0

मुझे विश्वास नहीं है कि यह मामला है। धारा के उदाहरण अलग हो सकते हैं, लेकिन सामग्री एक जैसी होनी चाहिए। यह मानते हुए कि उनके राज्य क्रमिकरण के दौरान संशोधित नहीं है। – Ian

+0

@Ian इसे बनाने के लिए मेरा नमूना कोड देखें। – Aliostad

उत्तर

6

जैसा कि मैंने उस SO प्रश्न की टिप्पणी में बताया है, स्ट्रिंग आउटपुट के अनुकूलन के कारण समस्या उत्पन्न हुई है (कम से कम मामला मैंने पाया है)। ऐसा लगता है कि तार एक ही संदर्भ हैं, तो यह इसे एक बार आउटपुट करेगा।

तो हम नमूना कोड किसी ऑब्जेक्ट के गुणों के लिए लंबी स्ट्रिंग का उपयोग करने के लिए क्या करते हैं और एक स्ट्रिंग और फिर धारावाहिक के संदर्भ को बदलते हैं। फिर ऑब्जेक्ट को फिर से स्ट्रीम करने के लिए स्ट्रीम को deserialise (और इस बार स्ट्रिंग इंटर्न किया गया है, उसी संदर्भ का उपयोग किया जाता है) और फिर फिर से serialise। इस बार स्ट्रीम छोटा है।

[Serializable] 
public class Proof 
{ 
    public string S1 { get; set; } 
    public string S2 { get; set; } 
    public string S3 { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 

     const string LongString = 
      "A value that is going to change the world nad iasjdsioajdsadj sai sioadj sioadj siopajsa iopsja iosadio jsadiojasd "; 

     var proof = new Proof() { 
      S1 = LongString, 
      S2 = LongString, 
      S3 = LongString 
     }; 

     proof.S2 = LongString.Substring(0, 10) + LongString.Substring(10); // just add up first 10 character with the rest. 
       //This just makes sure reference is not the same although values will be 

     Console.WriteLine(proof.S1 == proof.S2); 
     Console.WriteLine(proof.S1 == proof.S3); 
     Console.WriteLine(proof.S2 == proof.S3); 
     Console.WriteLine("So the values are all the same..."); 

     BinaryFormatter bf = new BinaryFormatter(); 
     MemoryStream stream = new MemoryStream(); 
     bf.Serialize(stream, proof); 
     byte[] buffer = stream.ToArray(); 
     Console.WriteLine("buffer length is " + buffer.Length); // outputs 449 on my machine 
     stream.Position = 0; 
     var deserProof = (Proof) bf.Deserialize(new MemoryStream(buffer)); 
     deserProof.S1 = deserProof.S2; 
     deserProof.S3 = deserProof.S2; 
     MemoryStream stream2 = new MemoryStream(); 
     new BinaryFormatter().Serialize(stream2, deserProof); 

     Console.WriteLine("buffer length now is " + stream2.ToArray().Length); // outputs 333 on my machine!! 
     Console.WriteLine("What? I cannot believe my eyes! Someone help me ........"); 

     Console.Read(); 
    } 
+0

अच्छा उदाहरण; मुझे यह दिलचस्प लगता है कि यह एक संदर्भ जांच करने में परेशानी के लिए चला गया, लेकिन विशेष-आवरण स्ट्रिंग समानता के बिना (क्योंकि यह एक आम बात है, खासकर जब डेटाबेस उदाहरण से मूल्य लोड करते हैं)। मैं एक खुश श्वास का आह्वान करता हूं कि * मेरा * धारावाहिक केवल संदर्भ समानता से अधिक के लिए तारों की जांच करना जानता है; पी –

+0

हाँ दोस्त, protobuf महान, अच्छा काम है। – Aliostad

+0

मुझे यह भी जोड़ना चाहिए: प्रोटोबफ भी इसकी गारंटी नहीं देता है। ठीक है, हकीकत में यह ** एक ही चीज़ को आउटपुट करेगा, लेकिन Google फोरम पर कुछ मूल डेटा-प्रकारों का प्रतिनिधित्व करते समय मुझे Google फोरम पर एक दिलचस्प चर्चा हुई थी (यानी ** डेटा के तरीके वैध रूप से ** उसी डेटा का प्रतिनिधित्व करते हैं जानबूझकर अतिरिक्त बाइट्स का उपयोग करना) –

1

जो आप 'वही' ऑब्जेक्ट कहते हैं उस पर थोड़ा निर्भर करता है।

लेकिन हाँ, 2 उदाहरण समान = सत्य के रूप में तुलना कर सकते हैं और अभी भी विभिन्न धाराओं का उत्पादन कर सकते हैं।

  • बराबर
  • क्योंकि normalizations या आपरेशन के आदेश की वजह से सूक्ष्म अंतर की की एक टूटी हुई या सीमित ओवरराइड के साथ बहुत तुच्छता।

मैंने सत्यापित किया कि एक अलग क्रम में एक शब्दकोश में एक ही तत्व जोड़ने से एक अलग धारा उत्पन्न होती है। मुझे लगता है कि आप एक ही सामग्री 'बराबर' के साथ 2 शब्दकोशों पर विचार करेंगे।

+0

एक बुरी तरह से लिखित धारावाहिक भी ऐसा करने में सक्षम हो सकता है?एक सीरिएलाइज़र की कल्पना करें जो यादृच्छिक डेटा आउटपुट करता है, उस क्षेत्र में जिसे deserialization के दौरान अनदेखा किया जाता है। – mah

+1

@mah: संभव लेकिन असंभव। लेकिन एक धारावाहिक अक्सर आईडी उत्पन्न करता है, इसे दोहराने योग्य तरीके से ऐसा करने का कोई कारण नहीं है। –

+0

@mah क्या .NET अंतर्निहित स्वरूपण में से कोई भी इस तरह से दूरस्थ रूप से व्यवहार करता है? मुझे पता है कि अगर आप इसे स्वयं लिखते हैं तो आप सभी तरह की अजीब चीजें कर सकते हैं, लेकिन .NET के साथ आने वाले लोगों के बारे में क्या? –

3

कुछ कोर प्रकार (DateTime - विशेष रूप से ध्यान देने योग्य बात "प्रकार", या Decimal पैमाने टिप्पण) मानों रिपोर्ट के रूप में बराबर हो सकता है, लेकिन जो अलग ढंग से क्रमानुसार; उदाहरण के लिए:

using System; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
[Serializable] 
class Foo 
{ 
    public decimal Bar { get; set; } 
    static void Main() 
    { 
     Foo foo = new Foo(); 
     foo.Bar = 123.45M; 
     var s = Serialize(foo); 

     Foo foo2 = new Foo(); 
     foo2.Bar = 123.4500M; 

     bool areSame = foo.Bar == foo2.Bar; // true 
     var s2 = Serialize(foo2); 

     bool areSerializedTheSame = s == s2; // false 
    } 
    static string Serialize(object obj) 
    { 
     using (var ms = new MemoryStream()) 
     { 
      new BinaryFormatter().Serialize(ms, obj); 
      return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length); 
     } 
    } 
} 

सटीक एक ही वस्तु को अलग ढंग से क्रमानुसार कर सकता था कि करने के लिए के रूप में - अच्छी तरह से, कि नहीं आम तौर पर एक गारंटी नहीं है कि क्रमांकन के बारे में कोई दावा करता है है। सीरियलाइजेशन आपके डेटा/ऑब्जेक्ट्स को संग्रहीत करने और पुनर्प्राप्त करने के बारे में है - समानता साबित करने के बारे में नहीं। उदाहरण के लिए, एक्सएमएल में सभी प्रकार के व्हाइटस्पेस और नेमस्पेस सामान्यीकरण मुद्दे हैं जो तुलना के लिए अनुपयुक्त बनाते हैं। BinaryFormatter और अन्य बाइनरी धारावाहिक अधिक आकर्षक लगते हैं, लेकिन मुझे यकीन नहीं है कि वे उस व्यवहार की गारंटी देते हैं जिसे आप ढूंढ रहे हैं।

मैं वास्तव में ऐसे दृष्टिकोण के माध्यम से तुलना की तुलना में विश्वास नहीं करता जब तक कि धारावाहिक स्पष्ट रूप से ने यह गारंटी नहीं दी।

+0

धन्यवाद मार्क। मैंने कुछ ऐसा भी रखा है जो तारों के संबंध में व्यवहार प्रदर्शित करता है। – Aliostad

संबंधित मुद्दे