Pertanyaan Bagaimana saya bisa menambahkan batasan tipe untuk memasukkan apa saja yang dapat serializable dalam metode umum?


Metode generik saya perlu membuat serial objek yang dilewatkan ke sana, namun hanya bersikeras bahwa ia mengimplementasikan ISerializable tampaknya tidak berfungsi. Sebagai contoh, saya memiliki struct kembali dari layanan web (ditandai dengan SerializableAttribute) yang bersambung ke xml baik-baik saja, tapi, seperti yang diharapkan, kompilator C # mengeluh.

Apakah ada cara saya dapat memeriksa objek serializable sebelum mencoba membuat cerita bersambung, atau, lebih baik lagi, cara menggunakan where kata kunci untuk memeriksa objek yang cocok?

Inilah metode lengkap saya:

public static void Push<T>(string url, T message)
        where T : ISerializable
{
    string xml = SerializeMessage(message);

    // Send the message to Amazon SQS
    SendMessageRequest sendReq = new SendMessageRequest { QueueUrl = url, MessageBody = xml };
    AmazonSQSClient client = new AmazonSQSClient(S3User, S3Pass);
    client.SendMessage(sendReq);
}

Dan SerializeMessage:

private static string SerializeMessage<T>(T message)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (StringWriter stringWriter = new StringWriter())
    {
        xmlSerializer.Serialize(stringWriter, message);
        return stringWriter.ToString();
    }
}

Jika ini tidak mungkin, apa cara terbaik untuk melakukan pemeriksaan bahwa suatu objek dapat dikategorikan pada saat runtime?


32
2018-06-03 15:45


asal


Jawaban:


Anda tidak dapat melakukan ini sepenuhnya melalui kendala umum, tetapi Anda dapat melakukan beberapa hal untuk membantu:

1) Masukkan baru() kendala pada tipe generik (untuk mengaktifkan kemampuan deserialize dan untuk memastikan XmlSerializer tidak mengeluh tentang kurangnya ctor default):

where T : new()

2) Pada baris pertama dari metode Anda menangani serialisasi (atau konstruktor atau di mana pun Anda tidak perlu mengulanginya berulang kali), Anda dapat melakukan pemeriksaan ini:

if( !typeof(T).IsSerializable && !(typeof(ISerializable).IsAssignableFrom(typeof(T)) ) )
    throw new InvalidOperationException("A serializable Type is required");

Tentu saja, masih ada kemungkinan pengecualian runtime ketika mencoba membuat serialisasi tipe, tetapi ini akan mencakup masalah yang paling jelas.


33
2018-06-03 15:50



Saya menulis artikel blog panjang tentang hal ini yang mungkin bermanfaat bagi Anda. Ini terutama masuk ke serialisasi biner tetapi konsep yang berlaku untuk sebagian besar format serialisasi.

Yang panjang dan pendek itu

  • Tidak ada cara untuk menambahkan kendala generik yang dapat diandalkan
  • Satu-satunya cara untuk memeriksa dan melihat apakah suatu objek adalah serializable adalah serialisasi dan melihat apakah operasi berhasil

7
2018-06-03 15:47



Satu-satunya cara untuk mengetahui apakah suatu objek dapat serializable adalah mencoba membuat cerita bersambung.

Bahkan, Anda bertanya bagaimana cara mengetahui apakah suatu tipe "dapat serialable", tetapi pertanyaan sebenarnya akan berkaitan dengan objek. Beberapa contoh dari suatu jenis mungkin tidak dapat diserialisasi meskipun jenisnya ditandai [Serializable]. Misalnya, bagaimana jika instance berisi referensi melingkar?


3
2018-06-03 15:48



Dari pada

XmlSerializer xmlSerializer = XmlSerializer baru (typeof (T));

mencoba

XmlSerializer xmlSerializer = new XmlSerializer (message.GetType ());


0
2018-06-03 15:47