একটি কাস্টম .NET ব্যতিক্রম সিরিয়ালাইজেবল করার সঠিক উপায় কী?


224

আরও সুনির্দিষ্টভাবে, যখন ব্যতিক্রমটিতে কাস্টম অবজেক্ট থাকে যা সেগুলি নিজেরাই সিরিয়ালযোগ্য হতে পারে বা নাও পারে।

এই উদাহরণটি ধরুন:

public class MyException : Exception
{
    private readonly string resourceName;
    private readonly IList<string> validationErrors;

    public MyException(string resourceName, IList<string> validationErrors)
    {
        this.resourceName = resourceName;
        this.validationErrors = validationErrors;
    }

    public string ResourceName
    {
        get { return this.resourceName; }
    }

    public IList<string> ValidationErrors
    {
        get { return this.validationErrors; }
    }
}

যদি এই ব্যতিক্রমটি সিরিয়ালযুক্ত এবং ডি-সিরিয়ালযুক্ত করা হয় তবে দুটি কাস্টম বৈশিষ্ট্য ( ResourceNameএবং ValidationErrors) সংরক্ষণ করা হবে না। সম্পত্তি ফিরে আসবে null

কাস্টম ব্যতিক্রমের জন্য সিরিয়ালাইজেশন বাস্তবায়নের জন্য কি একটি সাধারণ কোড প্যাটার্ন রয়েছে?

উত্তর:


411

বেস প্রয়োগ, কাস্টম বৈশিষ্ট্য ছাড়াই

SerializableExceptionWithoutCustomProperties.cs:

namespace SerializableExceptions
{
    using System;
    using System.Runtime.Serialization;

    [Serializable]
    // Important: This attribute is NOT inherited from Exception, and MUST be specified 
    // otherwise serialization will fail with a SerializationException stating that
    // "Type X in Assembly Y is not marked as serializable."
    public class SerializableExceptionWithoutCustomProperties : Exception
    {
        public SerializableExceptionWithoutCustomProperties()
        {
        }

        public SerializableExceptionWithoutCustomProperties(string message) 
            : base(message)
        {
        }

        public SerializableExceptionWithoutCustomProperties(string message, Exception innerException) 
            : base(message, innerException)
        {
        }

        // Without this constructor, deserialization will fail
        protected SerializableExceptionWithoutCustomProperties(SerializationInfo info, StreamingContext context) 
            : base(info, context)
        {
        }
    }
}

কাস্টম বৈশিষ্ট্য সহ সম্পূর্ণ বাস্তবায়ন

একটি কাস্টম সিরিয়ালযোগ্য ব্যতিক্রম ( MySerializableException) এবং একটি উত্পন্ন sealedব্যতিক্রম ( MyDerivedSerializableException) এর সম্পূর্ণ বাস্তবায়ন ।

এই বাস্তবায়ন সম্পর্কে প্রধান পয়েন্টগুলি এখানে সংক্ষিপ্ত করা হয়েছে:

  1. আপনাকে অবশ্যই প্রতিটি উত্সযুক্ত শ্রেণীর গুণাবলীটি [Serializable]সাজাতে হবে - এই বৈশিষ্ট্যটি বেস বর্গ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত নয়, এবং যদি এটি নির্দিষ্ট না করা হয়, তবে সিরিয়ালাইজেশনটি ব্যর্থ হবে SerializationExceptionযে "এসেম্বলি ওয়াইতে এক্স টাইপ এক্স ক্রমিক হিসাবে চিহ্নিত নয়" with
  2. আপনার অবশ্যই কাস্টম সিরিয়ালাইজেশন প্রয়োগ করতে হবে[Serializable]- একা অ্যাট্রিবিউট যথেষ্ট নয় Exceptionকার্যকরী ISerializableযার মানে আপনার উদ্ভূত শ্রেণীর কাস্টম ধারাবাহিকতাতে বাস্তবায়ন করতে হবে। এর মধ্যে দুটি পদক্ষেপ জড়িত:
    1. সিরিয়ালাইজেশন কনস্ট্রাক্টর সরবরাহ করুন । এই নির্মাণকারীটি privateযদি আপনার শ্রেণি হয় তবে sealedতা হওয়া উচিত, অন্যথায় এটি protectedউত্পন্ন ক্লাসে অ্যাক্সেসের অনুমতি দেওয়া উচিত ।
    2. গেটোবজেক্টডাটা () ওভাররাইড করুন এবং নিশ্চিত করুন যে আপনি base.GetObjectData(info, context)বেস ক্লাসটিকে তার নিজের রাষ্ট্রটি সংরক্ষণ করতে দিতে শেষ পর্যন্ত কল করেছেন ।

SerializableExceptionWithCustomProperties.cs:

namespace SerializableExceptions
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Security.Permissions;

    [Serializable]
    // Important: This attribute is NOT inherited from Exception, and MUST be specified 
    // otherwise serialization will fail with a SerializationException stating that
    // "Type X in Assembly Y is not marked as serializable."
    public class SerializableExceptionWithCustomProperties : Exception
    {
        private readonly string resourceName;
        private readonly IList<string> validationErrors;

        public SerializableExceptionWithCustomProperties()
        {
        }

        public SerializableExceptionWithCustomProperties(string message) 
            : base(message)
        {
        }

        public SerializableExceptionWithCustomProperties(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public SerializableExceptionWithCustomProperties(string message, string resourceName, IList<string> validationErrors)
            : base(message)
        {
            this.resourceName = resourceName;
            this.validationErrors = validationErrors;
        }

        public SerializableExceptionWithCustomProperties(string message, string resourceName, IList<string> validationErrors, Exception innerException)
            : base(message, innerException)
        {
            this.resourceName = resourceName;
            this.validationErrors = validationErrors;
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        // Constructor should be protected for unsealed classes, private for sealed classes.
        // (The Serializer invokes this constructor through reflection, so it can be private)
        protected SerializableExceptionWithCustomProperties(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            this.resourceName = info.GetString("ResourceName");
            this.validationErrors = (IList<string>)info.GetValue("ValidationErrors", typeof(IList<string>));
        }

        public string ResourceName
        {
            get { return this.resourceName; }
        }

        public IList<string> ValidationErrors
        {
            get { return this.validationErrors; }
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            info.AddValue("ResourceName", this.ResourceName);

            // Note: if "List<T>" isn't serializable you may need to work out another
            //       method of adding your list, this is just for show...
            info.AddValue("ValidationErrors", this.ValidationErrors, typeof(IList<string>));

            // MUST call through to the base class to let it save its own state
            base.GetObjectData(info, context);
        }
    }
}

DerivedSerializableExceptionWithAdditionalCustomProperties.cs:

namespace SerializableExceptions
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Security.Permissions;

    [Serializable]
    public sealed class DerivedSerializableExceptionWithAdditionalCustomProperty : SerializableExceptionWithCustomProperties
    {
        private readonly string username;

        public DerivedSerializableExceptionWithAdditionalCustomProperty()
        {
        }

        public DerivedSerializableExceptionWithAdditionalCustomProperty(string message)
            : base(message)
        {
        }

        public DerivedSerializableExceptionWithAdditionalCustomProperty(string message, Exception innerException) 
            : base(message, innerException)
        {
        }

        public DerivedSerializableExceptionWithAdditionalCustomProperty(string message, string username, string resourceName, IList<string> validationErrors) 
            : base(message, resourceName, validationErrors)
        {
            this.username = username;
        }

        public DerivedSerializableExceptionWithAdditionalCustomProperty(string message, string username, string resourceName, IList<string> validationErrors, Exception innerException) 
            : base(message, resourceName, validationErrors, innerException)
        {
            this.username = username;
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        // Serialization constructor is private, as this class is sealed
        private DerivedSerializableExceptionWithAdditionalCustomProperty(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            this.username = info.GetString("Username");
        }

        public string Username
        {
            get { return this.username; }
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            info.AddValue("Username", this.username);
            base.GetObjectData(info, context);
        }
    }
}

ইউনিট টেস্ট

উপরে বর্ণিত তিনটি ব্যতিক্রমের জন্য এমএসটিস্ট ইউনিট পরীক্ষা।

UnitTests.cs:

namespace SerializableExceptions
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTests
    {
        private const string Message = "The widget has unavoidably blooped out.";
        private const string ResourceName = "Resource-A";
        private const string ValidationError1 = "You forgot to set the whizz bang flag.";
        private const string ValidationError2 = "Wally cannot operate in zero gravity.";
        private readonly List<string> validationErrors = new List<string>();
        private const string Username = "Barry";

        public UnitTests()
        {
            validationErrors.Add(ValidationError1);
            validationErrors.Add(ValidationError2);
        }

        [TestMethod]
        public void TestSerializableExceptionWithoutCustomProperties()
        {
            Exception ex =
                new SerializableExceptionWithoutCustomProperties(
                    "Message", new Exception("Inner exception."));

            // Save the full ToString() value, including the exception message and stack trace.
            string exceptionToString = ex.ToString();

            // Round-trip the exception: Serialize and de-serialize with a BinaryFormatter
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                // "Save" object state
                bf.Serialize(ms, ex);

                // Re-use the same stream for de-serialization
                ms.Seek(0, 0);

                // Replace the original exception with de-serialized one
                ex = (SerializableExceptionWithoutCustomProperties)bf.Deserialize(ms);
            }

            // Double-check that the exception message and stack trace (owned by the base Exception) are preserved
            Assert.AreEqual(exceptionToString, ex.ToString(), "ex.ToString()");
        }

        [TestMethod]
        public void TestSerializableExceptionWithCustomProperties()
        {
            SerializableExceptionWithCustomProperties ex = 
                new SerializableExceptionWithCustomProperties(Message, ResourceName, validationErrors);

            // Sanity check: Make sure custom properties are set before serialization
            Assert.AreEqual(Message, ex.Message, "Message");
            Assert.AreEqual(ResourceName, ex.ResourceName, "ex.ResourceName");
            Assert.AreEqual(2, ex.ValidationErrors.Count, "ex.ValidationErrors.Count");
            Assert.AreEqual(ValidationError1, ex.ValidationErrors[0], "ex.ValidationErrors[0]");
            Assert.AreEqual(ValidationError2, ex.ValidationErrors[1], "ex.ValidationErrors[1]");

            // Save the full ToString() value, including the exception message and stack trace.
            string exceptionToString = ex.ToString();

            // Round-trip the exception: Serialize and de-serialize with a BinaryFormatter
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                // "Save" object state
                bf.Serialize(ms, ex);

                // Re-use the same stream for de-serialization
                ms.Seek(0, 0);

                // Replace the original exception with de-serialized one
                ex = (SerializableExceptionWithCustomProperties)bf.Deserialize(ms);
            }

            // Make sure custom properties are preserved after serialization
            Assert.AreEqual(Message, ex.Message, "Message");
            Assert.AreEqual(ResourceName, ex.ResourceName, "ex.ResourceName");
            Assert.AreEqual(2, ex.ValidationErrors.Count, "ex.ValidationErrors.Count");
            Assert.AreEqual(ValidationError1, ex.ValidationErrors[0], "ex.ValidationErrors[0]");
            Assert.AreEqual(ValidationError2, ex.ValidationErrors[1], "ex.ValidationErrors[1]");

            // Double-check that the exception message and stack trace (owned by the base Exception) are preserved
            Assert.AreEqual(exceptionToString, ex.ToString(), "ex.ToString()");
        }

        [TestMethod]
        public void TestDerivedSerializableExceptionWithAdditionalCustomProperty()
        {
            DerivedSerializableExceptionWithAdditionalCustomProperty ex = 
                new DerivedSerializableExceptionWithAdditionalCustomProperty(Message, Username, ResourceName, validationErrors);

            // Sanity check: Make sure custom properties are set before serialization
            Assert.AreEqual(Message, ex.Message, "Message");
            Assert.AreEqual(ResourceName, ex.ResourceName, "ex.ResourceName");
            Assert.AreEqual(2, ex.ValidationErrors.Count, "ex.ValidationErrors.Count");
            Assert.AreEqual(ValidationError1, ex.ValidationErrors[0], "ex.ValidationErrors[0]");
            Assert.AreEqual(ValidationError2, ex.ValidationErrors[1], "ex.ValidationErrors[1]");
            Assert.AreEqual(Username, ex.Username);

            // Save the full ToString() value, including the exception message and stack trace.
            string exceptionToString = ex.ToString();

            // Round-trip the exception: Serialize and de-serialize with a BinaryFormatter
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                // "Save" object state
                bf.Serialize(ms, ex);

                // Re-use the same stream for de-serialization
                ms.Seek(0, 0);

                // Replace the original exception with de-serialized one
                ex = (DerivedSerializableExceptionWithAdditionalCustomProperty)bf.Deserialize(ms);
            }

            // Make sure custom properties are preserved after serialization
            Assert.AreEqual(Message, ex.Message, "Message");
            Assert.AreEqual(ResourceName, ex.ResourceName, "ex.ResourceName");
            Assert.AreEqual(2, ex.ValidationErrors.Count, "ex.ValidationErrors.Count");
            Assert.AreEqual(ValidationError1, ex.ValidationErrors[0], "ex.ValidationErrors[0]");
            Assert.AreEqual(ValidationError2, ex.ValidationErrors[1], "ex.ValidationErrors[1]");
            Assert.AreEqual(Username, ex.Username);

            // Double-check that the exception message and stack trace (owned by the base Exception) are preserved
            Assert.AreEqual(exceptionToString, ex.ToString(), "ex.ToString()");
        }
    }
}

3
+1: তবে আপনি যদি এইরকম সমস্যায় চলে যান তবে আমি সমস্ত পথ দিয়ে চলে যাব এবং ব্যতিক্রমগুলি বাস্তবায়নের জন্য সমস্ত এমএস নির্দেশিকা অনুসরণ করব। আমি মনে রাখতে পারি একটি হ'ল স্ট্যান্ডার্ড কনস্ট্রাক্টর মাই এক্সেক্সেপশন (), মাই এক্সসেপশন (স্ট্রিং মেসেজ) এবং মাই এক্সসেপশন (স্ট্রিং মেসেজ, এক্সসেপশন ইনার এক্সেক্সশন)
জো

3
এছাড়াও - ফ্রেমওয়ার্ক ডিজাইনের গাইডলিনেস বলেছে যে ব্যতিক্রমগুলির নামগুলি "ব্যতিক্রম" দিয়ে শেষ হওয়া উচিত । MyExceptionAndHereIsaQualifyingAvverbialPrasse এর মতো কিছু অসম্পূর্ণ প্রস্তাবিত। msdn.microsoft.com/en-us/library/ms229064.aspx কেউ একবার বলেছিলেন, আমরা এখানে যে কোডটি সরবরাহ করি তা প্রায়শই একটি নিদর্শন হিসাবে ব্যবহৃত হয়, তাই এটি সঠিকভাবে পেতে আমাদের সতর্ক হওয়া উচিত।
চিজো

1
চিজো: কাস্টম ব্যতিক্রমগুলির ডিজাইনিং বিভাগের বিভাগে "ফ্রেমওয়ার্ক ডিজাইন গাইডলাইনস" বইটিতে বলা হয়েছে: "সমস্ত ব্যাতিক্রমের ক্ষেত্রে এই সাধারণ নির্মাতাদের সরবরাহ করুন (কমপক্ষে)"। এখানে দেখুন: ব্লগস.এমএসডিএন / কেসিওয়ালিনা / অর্কিভ / ২০০6 /০/0/০/0/ 6572726868৮.এসপিএক্স কেবল সিরিয়ালাইজেশন নির্ভুলতার জন্য (সিরিয়ালাইজেশন ইনফো তথ্য, স্ট্রিমিংকন্টেক্সট প্রসঙ্গ) কনস্ট্রাক্টরের প্রয়োজন, বাকিগুলি এটির জন্য একটি ভাল সূচনা পয়েন্ট তৈরি করার জন্য সরবরাহ করা হয়েছে কাটা-এবং-পেস্ট করুন। আপনি যখন কাটা এবং পেস্ট করবেন তবে আপনি অবশ্যই শ্রেণীর নাম পরিবর্তন করবেন, সুতরাং ব্যতিক্রম নামকরণের সম্মেলনটি লঙ্ঘন করা এখানে গুরুত্বপূর্ণ তা আমি মনে করি না ...
ড্যানিয়েল ফোর্টুনভ

3
.NET কোর হিসাবেও কি এই গৃহীত উত্তরটি সত্য? নেট কোর GetObjectDataকখনই ডাকা হয় না ... যাই হোক না কেন আমি ওভাররাইড করতে পারি ToString()যা
আমন্ত্রিত হয়ে যায়

3
দেখে মনে হচ্ছে এটি নতুন বিশ্বে এটি করা উপায় নয়। উদাহরণস্বরূপ, এএসপি.নেট কোরটিতে আক্ষরিকভাবে কোনও ব্যতিক্রম এইভাবে প্রয়োগ করা হয়নি। তারা সকলেই সিরিয়ালাইজেশন স্টাফগুলি
বিটবোনক

25

ব্যতিক্রম ইতিমধ্যে সিরিয়ালাইজযোগ্য, তবে GetObjectDataআপনার ভেরিয়েবলগুলি সংরক্ষণ করার জন্য আপনার পদ্ধতিটি ওভাররাইড করতে হবে এবং আপনার কনট্রাক্টর সরবরাহ করতে হবে যা আপনার অবজেক্টটিকে পুনরায় হাইড্রেট করার সময় বলা যেতে পারে।

সুতরাং আপনার উদাহরণটি হয়ে যায়:

[Serializable]
public class MyException : Exception
{
    private readonly string resourceName;
    private readonly IList<string> validationErrors;

    public MyException(string resourceName, IList<string> validationErrors)
    {
        this.resourceName = resourceName;
        this.validationErrors = validationErrors;
    }

    public string ResourceName
    {
        get { return this.resourceName; }
    }

    public IList<string> ValidationErrors
    {
        get { return this.validationErrors; }
    }

    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
    protected MyException(SerializationInfo info, StreamingContext context) : base (info, context)
    {
        this.resourceName = info.GetString("MyException.ResourceName");
        this.validationErrors = info.GetValue("MyException.ValidationErrors", typeof(IList<string>));
    }

    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);

        info.AddValue("MyException.ResourceName", this.ResourceName);

        // Note: if "List<T>" isn't serializable you may need to work out another
        //       method of adding your list, this is just for show...
        info.AddValue("MyException.ValidationErrors", this.ValidationErrors, typeof(IList<string>));
    }

}

1
প্রায়শই আপনি নিজের শ্রেণিতে কেবল [সিরিয়ালাইজযোগ্য] যুক্ত করে পালাতে পারেন।
হলগ্রিম

3
হলগ্রিম: সিরিয়ালাইজ করার জন্য আপনার অতিরিক্ত ক্ষেত্র থাকলে [সিরিয়ালাইজযোগ্য] যুক্ত করা যথেষ্ট নয়।
জো

2
এনবি: "ক্লাসটি সিল না করা থাকলে সাধারণভাবে এই কনস্ট্রাক্টরকে সুরক্ষিত করা উচিত" - সুতরাং আপনার উদাহরণে সিরিয়ালাইজেশন কনস্ট্রাক্টরকে সুরক্ষিত করা উচিত (বা, সম্ভবত আরও যথাযথভাবে, উত্তরাধিকার নির্দিষ্টভাবে প্রয়োজন না হলে ক্লাসটি সিল করা উচিত)। তা ছাড়া ভাল কাজ!
ড্যানিয়েল ফোর্টুনভ

এর মধ্যে আরও দুটি ভুল: [সিরিয়ালাইজযোগ্য] অ্যাট্রিবিউট বাধ্যতামূলক অন্যথায় সিরিয়ালাইজেশন ব্যর্থ হয়; গেটোবজেক্টডাটা অবশ্যই বেসে কল করতে হবে .গেটোবজেক্টডাটা
ড্যানিয়েল ফোর্টুনভ

8

ইস্রায়েলিজেবল কার্যকর করুন এবং এটি করার জন্য সাধারণ প্যাটার্ন অনুসরণ করুন ।

আপনাকে ক্লাসটি ট্যাগ করতে হবে [সিরিয়ালাইজেবল] অ্যাট্রিবিউটের সাথে, এবং সেই ইন্টারফেসের জন্য সমর্থন যুক্ত করতে হবে, এবং প্রচ্ছন্ন কন্সট্রাক্টরও যুক্ত করতে হবে (সেই পৃষ্ঠায় বর্ণিত, কোনও নির্মাণকারীকে অনুসন্ধান করবে )। আপনি টেক্সটের নীচে কোডটিতে এর প্রয়োগের একটি উদাহরণ দেখতে পাচ্ছেন।


8

উপরে সঠিক উত্তরের যোগ করার জন্য, আমি আবিষ্কার করেছি যে আমি আমার নিজস্ব বিশিষ্টতা সঞ্চয় এই কাস্টম ধারাবাহিকতাতে স্টাফ করছেন এড়াতে পারেন Dataসংগ্রহে এর Exceptionবর্গ।

উদাহরণ:

[Serializable]
public class JsonReadException : Exception
{
    // ...

    public string JsonFilePath
    {
        get { return Data[@"_jsonFilePath"] as string; }
        private set { Data[@"_jsonFilePath"] = value; }
    }

    public string Json
    {
        get { return Data[@"_json"] as string; }
        private set { Data[@"_json"] = value; }
    }

    // ...
}

ড্যানিয়েল প্রদত্ত সমাধানের তুলনায় সম্ভবত পারফরম্যান্সের ক্ষেত্রে এটি কম দক্ষ এবং সম্ভবত কেবলমাত্র "ইন্টিগ্রাল" ধরণের স্ট্রিং এবং ইন্টিজার এবং এর মতো কাজ করে।

তবুও এটি আমার পক্ষে খুব সহজ এবং খুব বোধগম্য ছিল।


1
অতিরিক্ত ব্যতিক্রম তথ্য হ্যান্ডল করার এটি একটি দুর্দান্ত এবং সহজ উপায় যেখানে আপনার কেবল এটি লগিংয়ের জন্য বা এর মতো কিছু সঞ্চয় করতে হবে। আপনি কি কখনও একটি ক্যাচ-ব্লক তথাপি তারপর আপনি বাইরে ডাটা মান যা এনক্যাপস্যুলেশন ইত্যাদি জন্য ভাল নয় সংবেদনশীল একজন বুদ্ধিমান উপর নির্ভর করা হবে এ কোডে এই অতিরিক্ত মান অ্যাক্সেস করতে প্রয়োজনীয় এমন
ক্রিস্টোফার রাজা

2
ওহ! ধন্যবাদ. আমি এলোমেলোভাবে আমার সমস্ত কাস্টম যুক্ত ভেরিয়েবলগুলি হারাতে থাকি যখনই কোনও ব্যতিক্রম পুনরায় ব্যবহার করা হয় throw;এবং এটি ঠিক করে দেয়।
নায়ারগডস

1
@ খ্রিস্টোফারকিং আপনার কীগুলি জানা দরকার? এগুলি গেটরে হার্ডকডযুক্ত।
নায়ারগডস

1

এমএসডিএন "দ্য ভাল স্বভাবের ব্যতিক্রম" তে এরিক গোনারসনের একটি দুর্দান্ত নিবন্ধ ছিল তবে এটি টানা হয়েছে বলে মনে হয়। ইউআরএলটি ছিল:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp08162001.asp

আইডসম্যানের উত্তর সঠিক, আরও তথ্য এখানে:

http://msdn.microsoft.com/en-us/library/ms229064.aspx

অ-সিরিয়ালাইজযোগ্য সদস্যদের সাথে ব্যাতিক্রমের জন্য আমি কোনও ব্যবহারের ক্ষেত্রে ভাবতে পারি না, তবে আপনি যদি সেগুলি গেটোবজেক্টডাটা এবং ডিসরিয়ালাইজেশন কনস্ট্রাক্টরকে সিরিয়ালাইজ / ডিসরিয়ালাইজ করার চেষ্টা এড়িয়ে যান তবে আপনার ঠিক আছে। এগুলি [ননশিরালাইজড] বৈশিষ্ট্যের সাথে চিহ্নিত করুন, যেহেতু আপনি নিজেই সিরিয়ালাইজেশন প্রয়োগ করছেন।


0

[সিরিয়ালাইজেবল] দিয়ে ক্লাসটি চিহ্নিত করুন, যদিও আমি নিশ্চিত নই যে সিরিয়ালাইজার দ্বারা কোনও আইলিস্ট সদস্য কতটা পরিচালনা করবেন।

সম্পাদনা

নীচের পোস্টটি সঠিক, কারণ আপনার কাস্টম ব্যতিক্রমটিতে এমন কনস্ট্রাক্টর রয়েছে যা পরামিতি নেয়, আপনাকে অবশ্যই ইস্রায়েলিজেবল প্রয়োগ করতে হবে।

যদি আপনি একটি ডিফল্ট নির্মাতা ব্যবহার করেন এবং দুটি কাস্টম সদস্যকে গেটর / সেটার বৈশিষ্ট্য সহ উন্মুক্ত করেন, আপনি কেবলমাত্র বৈশিষ্ট্যটি সেট করেই পালিয়ে যেতে পারেন।


-5

আমার ভাবতে হবে যে একটি ব্যতিক্রম সিরিয়ালিয়াল করা ইচ্ছুক একটি দৃ ind় ইঙ্গিত যে আপনি কোনও কিছুর প্রতি ভুল পদ্ধতির দিকে নিয়ে যাচ্ছেন। এখানে চূড়ান্ত লক্ষ্য কী? যদি আপনি দুটি প্রক্রিয়াগুলির মধ্যে বা একই প্রক্রিয়াটির পৃথক রানের মধ্যে ব্যতিক্রমটি অতিক্রম করে থাকেন তবে ব্যতিক্রমের বেশিরভাগ বৈশিষ্ট্য অন্য প্রক্রিয়ায় বৈধ হতে পারে না be

ক্যাচ () বিবৃতিতে আপনি যে স্টেটের তথ্য চান তা উত্তোলন করে এবং এটি সংরক্ষণাগারভুক্ত করা সম্ভবত আরও বেশি অর্থবোধ করবে।


9
ডাউনভোট - মাইক্রোসফ্টের নির্দেশিকাগুলি রাষ্ট্রের ব্যতিক্রমগুলি সিরিজযুক্তযোগ্য এমএসডিএন.মিকোসফটওয়্যার /en-us/library/ms229064.aspx হওয়া উচিত তাই এগুলি একটি অ্যাপডোমেন সীমানা জুড়ে ফেলে দেওয়া যেতে পারে, যেমন দূরবর্তী ব্যবহার করে।
জো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.