Не предназначен для этой конкретной цели, но ISerializationSurrogate
может помочь.
Я отредактирую и дополню свой ответ позже, но следующее выполняет то, что вам нужно, но не может достичь того же для вложенного objects.
Параметр obj здесь является экземпляром вашего класса. Мы просто опускаем добавление поля в информацию сериализации, если его значение равно нулю:
public class NullFieldOmittingSurrogate : ISerializationSurrogate
{
void ISerializationSurrogate.GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
if (obj != null)
{
foreach (FieldInfo field in obj.GetType().GetFields
(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
object fieldValue = field.GetValue(obj);
if (fieldValue != null)
{
info.AddValue(field.Name, fieldValue);
}
}
}
}
object ISerializationSurrogate.SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
// The deserialization works without the need for this surrogate
throw new NotImplementedException();
}
}
Нам нужно передать этот суррогат нашему двоичному форматеру, так что вот метод, который передает эту и другую необходимую информацию ему :
public static void SerializeObject(object myObjectInstance, Stream destinationStream)
{
SurrogateSelector surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate
(
myObjectInstance.GetType(),
new StreamingContext(StreamingContextStates.All),
new NullFieldOmittingSurrogate()
);
IFormatter serializer = new BinaryFormatter();
serializer.SurrogateSelector = surrogateSelector;
serializer.Serialize(destinationStream, myObjectInstance);
}
И, наконец, как использовать: (SerClass не имеет значения и является классом, имеющим 4 свойства типа object
для модульного тестирования)
public static void Main()
{
MemoryStream memoryStream = new MemoryStream();
SerializeObject
(
new SerClass()
{
Prop2 = 5,
Prop4 = "ABCD",
Nested = new SerClassNested() { Prop1 = 8, Prop3 = "EFGH" }
},
memoryStream
);
SerClass serClass = new BinaryFormatter().Deserialize(memoryStream) as SerClass;
}
Надеюсь, это помогает. Я все еще работаю над вложенными полями типов классов.