重写基于每个属性序列化的内容
本文关键字:序列化 属性 于每个 重写 | 更新日期: 2023-09-27 18:04:30
1(
我正在使用protobuf-net通过网络同步两个对象,因为我能够跟踪两个同步之间的更改,我只能发送更改的内容而不是整个对象。
所以基本上我想覆盖所有基于"脏"标志的可为空的属性序列化。
有没有一种"好"的方法可以做到这一点?(我可以忍受一个线程本地布尔值来修改我的属性getter的行为,但很好..(。
2((奖金问题(
我断断续续地序列化"真实"对象或通用 DTO 对象。但是我卡在了 DTO 上,通常我想序列化 <int, object>
的 KVP,这将是属性 id 及其数据,例如,它可以像Dictionary<string, Hashset<int>>
一样复杂,如果您知道类型,protobuf-net 可以很好地传输,但如果它被声明为对象,则不会。
一些建议将不胜感激,我在网上查看了,2(如果我处理由基本类型组成的嵌套泛型集合,似乎是一个死胡同。1( 如果我能改变行为,可以正常工作,但 DTO 仍然是完美的,因为它满足了传输更改而不是"完整对象"的需求......
protobuf-net支持标准的ShouldSerialize*
模式;因此对于属性Foo
,您可以添加:
private bool ShouldSerializeFoo() {
return /* true to serialize, false to omit */
}
请注意,在某些平台上,由于元编程/反射权限,该方法需要public
。另请注意,对于可为 null 的属性,如果不希望序列化它们,也可以简单地返回 null
。
我真的不明白你的第二个问题想做什么;你能澄清一下吗?
回复:#2 奖金问题
我不完全理解,但其中的某些部分听起来与我作为序列化混淆类型问题的解决方法而实现的东西非常相似。 该解决方案还允许序列化诸如Point
、Size
、Font
和Image
之类的东西。
我使用的"技巧"不是序列化类类型,而是将原始属性类型和字符串值提取到 TypeValue 对基元。 它们存储为可用于重建类对象的Dictionary<T, TypeValuePair>
。 Protobuf-net,然后只需要序列化一个常规的字典。
某些类类型的结果可能是一个听起来类似于您提到的内容的Dictionary<String, <Dictionary<T, TypeValuePair>>
。 您最终确实执行了类型转换,但这并不困难(VB,因为我无法快速编写 C#(:
' from TVP ctor
Sub New(v As Object) ' thing to convert
' convert whatever to string:
Dim conv As TypeConverter = TypeDescriptor.GetConverter(v.GetType)
_value = conv.ConvertToInvariantString(v)
...
' original type is stored as an enum (eg GenericTypes.Font)
_type = GenericConverter.GetGenericTypeCode(v)
End Sub
还有更多的事情,像Enum
和Bitmap
这样的一些事情必须以不同的方式处理,但只是轻微的。 为您的类/类型创建一个集合,并将其提交给 ProtoBuf。
我拆分了将字符串属性值转换回正确类型的过程。 TVP进行实际转换,但消费者进行选角。 TVP 的 TValue
属性重新创建原始数据类型,但返回一个 Object:
Public ReadOnly Property TValue As Object
Get
Dim R As Object = Nothing
Select Case _type
Case GenericTypes.TInt32
R = Int32.Parse(_value)
Case GenericTypes.TFont
R = TypeDescriptor.GetConverter(GetType(System.Drawing.Font)) _
.ConvertFromInvariantString(_value)
Case etc
End Select
Return R
End Get
End Property
我有一个类来容纳Dictionary<T, TypeValuePair>
并提供一些类似这样的函数:
Public Function GetTItem(Of TT)(key As T) As TT
If _col.ContainsKey(key) Then
' cast the object return to requested Type (TT)
Return CType(_col(key).TValue, TT)
Else
Return Nothing
End If
End Function
T
只是Dictionary<T, TypeValuePair>
中允许集合使用字符串或 int 键的T
。 如果您愿意,TT
可以传递给TValue
。 GetTItem
行为是由原始类将其强制转换为请求的类型,该类确实知道其自身属性的类型,因此没有做出可疑的假设:
' get item enum.N and cast to Int32:
_ziggys = myThing.GetTItem(Of Int32)(PropIndexEnum.Ziggys)
正如我所说,我不确定这会有所帮助,但你的情况听起来很熟悉。 要序列化的任何类对象只需要能够以可序列化的形式咳出其构成属性,而不是尝试将Object
提交到序列化程序。 当然,这都是开销,在高容量情况下可能太多了,但它可以工作。