2010-03-09 7 views
3

Я хочу создать общий метод serizlize класс в текст (для использования в качестве части сетевого компонента) Метод должен быть что-то вроде:тест, если класс может быть сериализовать

public string SerializeToText<T>(T DataToSerialize); 

Метод содержимое просто выполнило бы сериализацию xml, и я могу это сделать. Я хочу знать, могу ли я проверить, может ли быть сериализована T: желательно во время компиляции, но в противном случае во время выполнения.

+0

Довольно уверен, что это обман, и по крайней мере один ответ является точным обманом http: // stackoverflow.com/questions/81674/how-to-check-if-an-object-is-serializable-in-c –

+0

Нет. Этот вопрос задает в первую очередь вопрос о проверке во время компиляции. Этот предыдущий вопрос задает только проверку времени выполнения. Многие из ответов здесь могут быть дубликатами, но только потому, что их авторы недостаточно внимательно читают этот вопрос! :) –

ответ

4

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

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

[Serialiable] 
class Foo { 
    public object Field; 
} 
class Bar { } 

var value = new Foo() { Field1 = 42; } // value is serializable 
value.Field1 = new Bar(); // value is no longer serializable 

Я написал длинную статью в блоге по вопросам, касающимся определения того, является ли объект сериализуемым или нет. В нем рассматриваются проблемы с этим типом подхода в глубину.

0

Класс может быть включен для сериализации, просто применив атрибут к его определению. И нет никакого способа в C# сделать ошибку времени компиляции, потому что в типе отсутствует атрибут, поэтому нет, вы не можете поймать попытки сериализации unserializable типа во время компиляции.

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

Также есть небольшая точка, делающая ваш общий метод обертки. Аргумент может быть любого типа, без ограничений, которые могли бы с пользой его ограничить, поэтому он может быть простым старым object.

Однако, если вы избегаете встроенной среды сериализации .NET, вы можете разработать свой собственный, который проверяется временем компиляции. Вам нужно будет использовать систему типов соответствующим образом, то есть определить интерфейс, который должен реализовать любой сериализуемый тип. Тогда ваш метод SerializeToText примет ссылку на этот интерфейс.

interface ICanSerialize 
{ 
    void Serialize(ISerializeMedium m); 
} 

interface ISerializeMedium 
{ 
    void Serialize(string name, ref int value); 
    void Serialize(string name, ref bool value); 
    void Serialize(string name, ref string value); 
    void Serialize<T>(string name, ref T value) where T : ICanSerialize; 
    void Serialize<T>(string name, ref ICollection<T> value) where T : ICanSerialize; 

    // etc. 
} 

сериализуемый тип будет выглядеть следующим образом:

class C : ICanSerialize 
{ 
    string _firstName; 
    bool _happy; 

    public void Serialize(ISerializeMedium m) 
    { 
     m.Serialize("firstName", ref _firstName); 
     m.Serialize("happy", ref _happy); 
    } 
} 

Тогда вам просто необходима реализация ISerializeMedium. Такая структура накладывает безопасность типов на все виды использования сериализации с нуля, а не на то, чтобы последовать за ней, что невозможно.

Все это связано с определенным количеством переоборудования колес, но иногда вам требуется круглое колесо.

-1

Вы ссылаетесь на это сообщение?

if (typeof(T).IsSerializable) 
+0

См. Ответ Джареда, почему это просто не так просто. –

+0

ОК. Я писал свой ответ, когда Джаред Пар писал свой ответ, поэтому я не читал его перед публикацией. – Javier

Смежные вопросы