Подтвердить что ты не робот

Как добавить ограничение типа для включения любого сериализуемого в общий метод?

Мой общий метод должен сериализовать переданный ему объект, однако просто настаивая на том, что он реализует ISerializable, похоже, не работает. Например, у меня есть структура, возвращаемая из веб-службы (помеченная SerializableAttribute), которая сериализуется в xml просто отлично, но, как и ожидалось, компилятор С# жалуется.

Есть ли способ проверить, что объект сериализуется, прежде чем пытаться его сериализовать, или, что еще лучше, использовать ключевое слово where для проверки объекта?

Здесь мой полный метод:

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);
}

И 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();
    }
}

Если это невозможно, то какой лучший способ выполнить проверку того, что объект сериализуется во время выполнения?

4b9b3361

Ответ 1

Вы не можете сделать это полностью через общие ограничения, но вы можете сделать пару вещей, чтобы помочь:

1) Поместите ограничение new() на общий тип (чтобы включить возможность десериализации и убедиться, что XmlSerializer не жалуется на отсутствие по умолчанию ctor):

where T : new()

2) В первой строке вашего метода, обрабатывающей сериализацию (или конструктор или где-либо еще, вам не нужно повторять его снова и снова), вы можете выполнить эту проверку:

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

Конечно, есть еще возможность исключений во время выполнения при попытке сериализации типа, но это будет охватывать наиболее очевидные проблемы.

Ответ 2

Я написал статью в блоге по этой теме, которую вы можете найти полезной. Он в основном идет в двоичную сериализацию, но концепции применимы к большинству любых форматов сериализации.

Длинные и короткие

  • Невозможно добавить надежное общее ограничение
  • Единственный способ проверить и посмотреть, был ли сериализуемый объект сериализуемым, - это сериализовать его и посмотреть, удастся ли выполнить операцию

Ответ 3

Единственный способ узнать, является ли объект сериализуемым, - попытаться его сериализовать.

На самом деле вы спрашивали, как определить, является ли тип "сериализуемым", но фактический вопрос будет касаться объектов. Некоторые экземпляры типа не могут быть сериализованы, даже если тип отмечен [Serializable]. Например, что, если экземпляр содержит циклические ссылки?

Ответ 4

Вместо

XmlSerializer xmlSerializer = новый XmlSerializer (typeof (T));

попробуйте

XmlSerializer xmlSerializer = новый XmlSerializer (message.GetType());