我正在尝试创建一个简单的内存网格,可以使用协议缓冲区进行序列化。
这个想法是用户可以创建/定义任何类型的列(基元或用户定义的列,只要它们是标记的协议缓冲区)。
我的问题是您无法使用协议缓冲区序列化类型数据,那么我该如何实现呢?
代码如下,显示我希望如何编码网格的列。
非常感谢。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Column colOrderId = new Column("OrderId", typeof(uint));
Column colOrderDesc = new Column("OrderDesc", typeof(string));
Column colPrice = new Column("Price", typeof(Price));
Column colOrderDateTime = new Column("OrderDateTime", typeof(DateTime));
var s = colOrderId.ToBArray();
}
}
[ProtoContract, Serializable]
public sealed class Column
{
public Column(string name, Type type)
{
Name = name;
Type = type;
}
[ProtoMember(1)]
public string Name { get; private set; }
[ProtoMember(2)]
public Type Type { get; private set; }
}
[ProtoContract, Serializable]
public sealed class Price
{
public Price(double value, string currency)
{
Value = value;
Currency = currency;
}
[ProtoMember(1)]
public double Value { get; private set; }
[ProtoMember(2)]
public string Currency { get; private set; }
}
public static class ProtoBufEx
{
public static byte[] ToBArray<T>(this T o)
{
using (MemoryStream ms = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(ms, o);
return ms.ToArray();
}
}
}
答案 0 :(得分:1)
这种方法存在一些问题;是的,在标准协议缓冲区中,任何类型的Type
元数据都有点顽皮,因为它不是真正的可互操作性,但我在v2 的基础上选择加入了一点松散 - 允许您发送object
等,只要在内部它仍然知道您的意思。
然而,这对于逐个单元格的工作来说会变得很昂贵,甚至内置优化(例如,它只发送一次相同类型的元数据)。
但是,IMO,更好的选择是将自己限制在一个已知类型的列表中,这些类型都是提前知道的。如果你可以 ,那么有一些有趣的继承技巧非常有效并且非常适合这种情况。但基本上你有类似的东西:[ProtoContract]
[ProtoInclude(4, typeof(Column<int>))] // etc
abstract class Column {
[ProtoMember(1)]
public string Name {get;private set;}
public abstract object Value {get;private set;}
}
[ProtoContract]
class Column<T> : Column {
[ProtoMember(1)]
public T TypedValue { get;private set;}
override Value {...shim to TypedValue...}
}
// etc
(伪代码,不完整)
我很高兴地向您介绍了很多内容,但您可能还想查看this blog entry以查看是否使用DataTable
(就像我不喜欢数据访问一样)可能会节省这里有一些努力。