Также на несколько другой банке
кто-то объясняет, почему этот атрибут
необходимо
Давайте посмотрим:
Во время сериализации BinaryFormatter вызывает методы класса FormatterServices. Один из них
private static MemberInfo[] InternalGetSerializableMembers(RuntimeType type)
Этот метод содержит следующий код:
if (!CheckSerializable(type))
{
throw new SerializationException(Environment.GetResourceString("Serialization_NonSerType", new object[] { type.FullName, type.Module.Assembly.FullName }));
}
позволяет проверить метод CheckSerializable класса FormatterServices:
private static bool CheckSerializable(RuntimeType type)
{
return type.IsSerializable;
}
Этот код похож на:
Type t = typeof (SomeClass);
bool isTypeSerializable = t.IsSerializable;
В этом примере isTypeSerializable будет иметь значение true, если класс SomeClass имеет SerializableAttribute. В противном случае ложь.
Soo ... Простой ответ: этот атрибут flag , который указывает, что экземпляры класса могут быть сериализованы. Так что это просто нужно, и это все.
Относительно вашего основного вопроса:
К сожалению, вы не можете использовать двоичный форматер для экземпляра класса, определенного в сборке silverlight напрямую.
Один из способов сделать это - использовать прокси-класс.
Пример:
Класс внутри вашей сборки Silverlight:
public class SomeClass
{
public int IntValue { get; set; }
public string StringValue { get; set; }
public bool BoolValue { get; set; }
}
Прокси-класс, который поддерживает сериализацию внутри общей сборки .NET со ссылкой на сборку silverlight:
[Serializable]
public class SomeClassProxy
{
public int IntValue { get; set; }
public string StringValue { get; set; }
public bool BoolValue { get; set; }
public static SomeClassProxy GetSerializableObject(SomeClass silverlightClass)
{
return new SomeClassProxy
{
IntValue = silverlightClass.IntValue,
StringValue = silverlightClass.StringValue,
BoolValue = silverlightClass.BoolValue
};
}
public static SomeClass DeserializeSilverlightCompatible(Stream stream)
{
BinaryFormatter formatter = new BinaryFormatter();
SomeClassProxy proxy = formatter.Deserialize(stream) as SomeClassProxy;
return new SomeClass
{
IntValue = proxy.IntValue,
StringValue = proxy.StringValue,
BoolValue = proxy.BoolValue
};
}
}
Так что в ваших приложениях asp .net или winforms вы должны работать с прокси-классом:
using(MemoryStream memoryStream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
//create instance of silverlight class
SomeClass mySilverlightClass = new SomeClass();
mySilverlightClass.IntValue = 555;
mySilverlightClass.StringValue = "Hello World!";
mySilverlightClass.BoolValue = true;
//<===serialize and take care of silverlight instance
formatter.Serialize(memoryStream, SomeClassProxy.GetSerializableObject(mySilverlightClass));
memoryStream.Seek(0, SeekOrigin.Begin);
//===>deserialize to silverlight instance
SomeClass mySilverlightClassRestored = SomeClassProxy.DeserializeSilverlightCompatible(memoryStream);
}
Таким образом, этот прокси-сервер заботится как о сериализации, так и о десериализации (после десериализации вы получите экземпляр класса SomeClass, определенный в сборке silverlight).
Если двоичный форматер имеет мягкое ограничение, то я могу порекомендовать вам вместо этого использовать сериализатор xml:
XmlSerializer s = new XmlSerializer(typeof(SomeClass));
s.Serialize(memoryStream, mySilverlightClass);
memoryStream.Seek(0, SeekOrigin.Begin);
SomeClass restored = s.Deserialize(memoryStream) as SomeClass;
В этом случае SerializableAttribute не нужен.