সি # তে কোনও বস্তু সিরিয়ালযোগ্য কিনা তা কীভাবে পরীক্ষা করবেন


94

সি # তে কোনও বস্তু সিরিয়ালযোগ্য কিনা তা পরীক্ষা করার জন্য আমি একটি সহজ উপায় সন্ধান করছি।

যেমনটি আমরা জানি যে আপনি হয় ইরিশরিজযোগ্য ইন্টারফেস বাস্তবায়ন করে বা [সিরিয়ালাইজযোগ্য] শ্রেণীর শীর্ষে রেখে কোনও অবজেক্টকে সিরিয়ালাইজ করতে সক্ষম করেছেন ।

আমি যা খুঁজছি তা হল ক্লাসটির বৈশিষ্ট্যগুলি প্রতিফলিত না করে এটি পরীক্ষা করার দ্রুত উপায়। ইন্টারফেসটি একটি ইস স্টেটমেন্ট ব্যবহার করে দ্রুত হবে ।

@ ফ্লার্ডের পরামর্শটি ব্যবহার করে এই কোডটি আমি এনেছি, চিৎকার করার আরও ভাল উপায় আছে।

private static bool IsSerializable(T obj)
{
    return ((obj is ISerializable) || (Attribute.IsDefined(typeof (T), typeof (SerializableAttribute))));
}

বা আরও ভাল কেবল অবজেক্টের ধরণটি পান এবং তারপরে এই ধরণের ইসেরাইরিজেবল সম্পত্তি ব্যবহার করুন:

typeof(T).IsSerializable

মনে রাখবেন যদিও এটি কেবলমাত্র ক্লাসটিকেই মনে হচ্ছে যা আমরা কেবল সেই শ্রেণীর সাথেই আচরণ করছি যা যদি ক্লাসে অন্যান্য ক্লাস থাকে তবে আপনি সম্ভবত তাদের সমস্ত পরীক্ষা করতে বা সিরিয়ালাইজ করতে চান এবং @ পিবি নির্দেশিত হিসাবে ত্রুটির জন্য অপেক্ষা করতে চান।


4
দুঃখিত যে আপত্তি যখন একটি ক্ষেত্র ক্রমিকায়িত হয় না, ব্যর্থ হয়, আমার নমুনা দেখুন।
পল ভ্যান ব্রেনক

আমি মনে করি এটি অনেক উন্নত পদ্ধতি: স্ট্যাকওভারফ্লো.com
জিরো

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

উত্তর:


115

আপনার কাছে Typeক্লাসে একটি সুন্দর সম্পত্তি আছে IsSerializable


7
সিরিয়ালাইজেবলের কোনও বৈশিষ্ট্য আপনার শ্রেণীর সাথে সংযুক্ত থাকলে এটি আপনাকে কেবল অবহিত করবে।
ফাতেমা

37
তার বক্তব্যটি হ'ল সেই বস্তুর সদস্যগুলি সমেত প্রকারের সত্ত্বেও সিরিয়ালযোগ্য হতে পারে না। ঠিক? এটি কি এমন নয় যে আমাদের অবশ্যই অবশ্যই সেই বস্তুর সদস্যদের মধ্যে পুনরাবৃত্তভাবে ড্রিল করতে হবে এবং প্রত্যেকে পরীক্ষা করে দেখতে হবে, যদি এটি কেবল সিরিয়াল করার চেষ্টা না করে দেখুন এবং এটি ব্যর্থ হয় কিনা?
ব্রায়ান সুইভিনে

4
উদাহরণস্বরূপ <সোমেডটিও> << সোডেমটিটো> সিমডটিও সিরিয়ালযোগ্য না হলেও এমন কি সত্য
সাইমন ডাউডসওয়েল

43

সিরিয়ালাইজযোগ্য বৈশিষ্ট্যের জন্য আপনাকে সিরিজযুক্ত বস্তুর গ্রাফের সমস্ত ধরণের পরীক্ষা করতে হবে। সবচেয়ে সহজ উপায় হ'ল অবজেক্টটিকে সিরিয়ালাইজ করার চেষ্টা করা এবং ব্যতিক্রমটি ধরা। (তবে এটি সবচেয়ে পরিষ্কার সমাধান নয়)। প্রকার।

নমুনা

[Serializable]
public class A
{
    public B B = new B();
}

public class B
{
   public string a = "b";
}

[Serializable]
public class C
{
    public D D = new D();
}

[Serializable]
public class D
{
    public string d = "D";
}


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

        var a = typeof(A);

        var aa = new A();

        Console.WriteLine("A: {0}", a.IsSerializable);  // true (WRONG!)

        var c = typeof(C);

        Console.WriteLine("C: {0}", c.IsSerializable); //true

        var form = new BinaryFormatter();
        // throws
        form.Serialize(new MemoryStream(), aa);
    }
}

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

এই উত্তর ক্রিয়াকলাপটি রাউন্ড ট্রিপ করতে পারে কিনা তা পরীক্ষা করতে ক্লোনিং ব্যবহার করে। কিছু ক্ষেত্রে এটা Overkill হতে পারে যদিও ধারাবাহিকতাতে কিছু সদস্য সেট করতে আশা করা হয় না হয়েছিল: stackoverflow.com/questions/236599/...
VoteCoffee

18

এটি একটি পুরানো প্রশ্ন, এটি .NET 3.5+ এর জন্য আপডেট করার প্রয়োজন হতে পারে। টাইপ.আইএসআরসিরিজেবল আসলে ক্লাসে ডেটা কন্ট্র্যাক্ট বৈশিষ্ট্য ব্যবহার করে মিথ্যা ফিরিয়ে দিতে পারে। এখানে আমি ব্যবহার করি একটি স্নিপেট, এটি যদি দুর্গন্ধযুক্ত হয় তবে আমাকে জানান :)

public static bool IsSerializable(this object obj)
{
    Type t = obj.GetType();

     return  Attribute.IsDefined(t, typeof(DataContractAttribute)) || t.IsSerializable || (obj is IXmlSerializable)

}

4
পুরানো প্রশ্ন এবং পুরানো উত্তর তবে এটি খুব সত্য! Type.IsSerializable কেবল একটি আংশিক-কার্যকরী সমাধান। প্রকৃতপক্ষে, আজকাল ডাব্লুসিএফ এবং ডেটা কন্ট্র্যাক্টগুলির মধ্যে কতজন ব্যবহার করে, এটি আসলে একটি খুব দুর্বল সমাধান!
জ্যাক্সিডিয়ান

আপত্তি যদি নাল হিসাবে আসে?
N73k

@ N73k একটি nullচেক করুন এবং ফিরে যদি true?
ফ্রেডএম

9

অন্যরা যেমন উল্লেখ করেছে তেমন টাইপ.আইএসআরশায়ারাইজাল ব্যবহার করুন।

প্রতিফলিত করার চেষ্টা করা এবং অবজেক্ট গ্রাফের সমস্ত সদস্য ক্রমিকায়িতযোগ্য কিনা তা পরীক্ষা করা সম্ভবত উপযুক্ত নয় not

কোনও সদস্যকে সিরিয়ালাইজযোগ্য টাইপ হিসাবে ঘোষণা করা যেতে পারে, তবে আসলে নিম্নলিখিত উত্সর্গীকৃত উদাহরণ হিসাবে সিরিয়ালযোগ্য নয় এমন একটি উদ্ভূত প্রকার হিসাবে তাত্ক্ষণিকভাবে চিহ্নিত করা যেতে পারে:

[Serializable]
public class MyClass
{
   public Exception TheException; // serializable
}

public class MyNonSerializableException : Exception
{
...
}

...
MyClass myClass = new MyClass();
myClass.TheException = new MyNonSerializableException();
// myClass now has a non-serializable member

সুতরাং, এমনকি যদি আপনি নির্ধারণ করেন যে আপনার ধরণের একটি নির্দিষ্ট উদাহরণটি সিরিয়ালাইজযোগ্য, আপনি সাধারণভাবে নিশ্চিত হতে পারবেন না যে এটি সমস্ত ক্ষেত্রে সত্য হবে true



5

এখানে একটি 3.5 প্রকরণ রয়েছে যা এটি একটি বর্ধিতকরণ পদ্ধতি ব্যবহার করে সমস্ত শ্রেণিতে উপলব্ধ করে।

public static bool IsSerializable(this object obj)
{
    if (obj is ISerializable)
        return true;
    return Attribute.IsDefined(obj.GetType(), typeof(SerializableAttribute));
}

2

আমি এই প্রশ্নের উত্তর এবং উত্তরটি এখানে নিয়েছি এবং এটি সংশোধন করেছি যাতে আপনি এমন ধরণের তালিকা পান যা সিরিয়ালযোগ্য নয়। কোনটি চিহ্নিত করতে হবে তা সহজেই আপনি জানতে পারবেন।

    private static void NonSerializableTypesOfParentType(Type type, List<string> nonSerializableTypes)
    {
        // base case
        if (type.IsValueType || type == typeof(string)) return;

        if (!IsSerializable(type))
            nonSerializableTypes.Add(type.Name);

        foreach (var propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (propertyInfo.PropertyType.IsGenericType)
            {
                foreach (var genericArgument in propertyInfo.PropertyType.GetGenericArguments())
                {
                    if (genericArgument == type) continue; // base case for circularly referenced properties
                    NonSerializableTypesOfParentType(genericArgument, nonSerializableTypes);
                }
            }
            else if (propertyInfo.GetType() != type) // base case for circularly referenced properties
                NonSerializableTypesOfParentType(propertyInfo.PropertyType, nonSerializableTypes);
        }
    }

    private static bool IsSerializable(Type type)
    {
        return (Attribute.IsDefined(type, typeof(SerializableAttribute)));
        //return ((type is ISerializable) || (Attribute.IsDefined(type, typeof(SerializableAttribute))));
    }

এবং তারপর আপনি এটি কল ...

    List<string> nonSerializableTypes = new List<string>();
    NonSerializableTypesOfParentType(aType, nonSerializableTypes);

এটি যখন চলবে, ননশিরাইজেবল টাইপগুলির তালিকা থাকবে। খালি তালিকায় পুনরাবৃত্তির পদ্ধতিতে পাস করার চেয়ে এটি করার আরও ভাল উপায় হতে পারে। কেউ যদি আমাকে সংশোধন করেন।


0

ব্যতিক্রম বস্তুটি সিরিয়ালযোগ্য হতে পারে তবে অন্য ব্যতিক্রমগুলি ব্যবহার করে যা তা নয়। ডাব্লুসিএফ সিস্টেমের সাথে আমার সবেমাত্র এটি ছিল .সেবারমোডেল .ফাল্ট এক্সপ্লেশন: ফল্টএক্সেপশন সিরিয়ালাইজযোগ্য তবে এক্সসেপশনডেটেল নয়!

সুতরাং আমি নিম্নলিখিত ব্যবহার করছি:

// Check if the exception is serializable and also the specific ones if generic
var exceptionType = ex.GetType();
var allSerializable = exceptionType.IsSerializable;
if (exceptionType.IsGenericType)
    {
        Type[] typeArguments = exceptionType.GetGenericArguments();
        allSerializable = typeArguments.Aggregate(allSerializable, (current, tParam) => current & tParam.IsSerializable);
    }
 if (!allSerializable)
    {
        // Create a new Exception for not serializable exceptions!
        ex = new Exception(ex.Message);
    }

0

আমার সমাধান, ভিবি.নেটে:

অবজেক্টের জন্য:

''' <summary>
''' Determines whether an object can be serialized.
''' </summary>
''' <param name="Object">The object.</param>
''' <returns><c>true</c> if object can be serialized; otherwise, <c>false</c>.</returns>
Private Function IsObjectSerializable(ByVal [Object] As Object,
                                      Optional ByVal SerializationFormat As SerializationFormat =
                                                                            SerializationFormat.Xml) As Boolean

    Dim Serializer As Object

    Using fs As New IO.MemoryStream

        Select Case SerializationFormat

            Case Data.SerializationFormat.Binary
                Serializer = New Runtime.Serialization.Formatters.Binary.BinaryFormatter()

            Case Data.SerializationFormat.Xml
                Serializer = New Xml.Serialization.XmlSerializer([Object].GetType)

            Case Else
                Throw New ArgumentException("Invalid SerializationFormat", SerializationFormat)

        End Select

        Try
            Serializer.Serialize(fs, [Object])
            Return True

        Catch ex As InvalidOperationException
            Return False

        End Try

    End Using ' fs As New MemoryStream

End Function

প্রকারের জন্য:

''' <summary>
''' Determines whether a Type can be serialized.
''' </summary>
''' <typeparam name="T"></typeparam>
''' <returns><c>true</c> if Type can be serialized; otherwise, <c>false</c>.</returns>
Private Function IsTypeSerializable(Of T)() As Boolean

    Return Attribute.IsDefined(GetType(T), GetType(SerializableAttribute))

End Function

''' <summary>
''' Determines whether a Type can be serialized.
''' </summary>
''' <typeparam name="T"></typeparam>
''' <param name="Type">The Type.</param>
''' <returns><c>true</c> if Type can be serialized; otherwise, <c>false</c>.</returns>
Private Function IsTypeSerializable(Of T)(ByVal Type As T) As Boolean

    Return Attribute.IsDefined(GetType(T), GetType(SerializableAttribute))

End Function
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.