我对 C# 语言相当陌生,所以我只是不明白为什么我的构建会产生如下错误消息。
The type or namespace name 'ProtoBuf' could not be found(are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我以“.NET Framework 3.5”为目标,我不会收到错误,但一旦将项目设置为以“.NET Framework 2.0”为目标,我就会收到错误代码保持不变,protobuf-net 应该是使用 .NET 2.0 所以我不确定我错过了什么。仅供参考,导致上述错误的行是这一行:
using ProtoBuf;
Run Code Online (Sandbox Code Playgroud)
谁能给我一些建议来解决上述错误?先感谢您。
我使用的是 v2 rev 421。当我保存 protobuf-net 生成的流并将其放入字符串实用程序时,它发现了许多重复的字符串。我说的是应用程序生成的字符串,它可以被实习,但默认情况下字符串实习似乎没有打开。
我如何启用它?
谢谢。
作为 protobuf 协议的一部分,我需要能够发送动态类型的数据,有点像VARIANT。粗略地说,我要求数据是整数、字符串、布尔值或“其他”,其中“其他”(例如DateTime)被序列化为字符串。我需要能够将它们用作单个字段并在协议中多个不同位置的列表中使用。
如何才能最好地实现这一点,同时保持消息大小最小和性能最佳?
我正在使用 protobuf-net 和 C#。
编辑:
我在下面发布了一个建议的答案,其中使用了我认为所需的最小内存。
EDIT2:在http://github.com/pvginkel/ProtoVariant创建了一个具有完整实现的
github.com 项目。
出于性能原因,我在反序列化保存数据的程序集与序列化数据的程序集相同的情况下使用protobuf-net 。
我序列化的大多数类型都是用ProtoContract和ProtoMember属性标记的简单合约,但有时我必须序列化具有许多子类的奇怪对象(即:Exception)。
我使用经典的 ISerialized 机制通过以下解决方法使其工作。
我对 protobuf-net 很陌生,想知道这是否是一个好主意以及是否有更好/标准的方法来做到这一点。
我的解决方法:
我定义了一个实现经典序列化的通用代理
[ProtoContract]
class BinarySerializationSurrogate<T>
{
[ProtoMember(1)]
byte[] objectData = null;
public static implicit operator T(BinarySerializationSurrogate<T> surrogate)
{
T ret = default(T);
if (surrogate == null)
return ret;
var serializer = new BinaryFormatter();
using (var serializedStream = new MemoryStream(surrogate.objectData))
ret = (T)serializer.Deserialize(serializedStream);
return ret;
}
public static implicit operator BinarySerializationSurrogate<T>(T obj)
{
if (obj == null)
return null;
var ret = new BinarySerializationSurrogate<T>();
var …Run Code Online (Sandbox Code Playgroud) 假设我有以下课程:
public class Test {
int x { get; set; }
int y { get; set; }
Vector3 coords { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果我不能在来自外部程序集的类上使用[ProtoContract]和[ProtoMember(x)]属性,我该如何序列化这个对象Vector3。
我已阅读如何使用 protobuf-net 或其他序列化程序序列化 3rd 方类型?但它很模糊(例如,我不知道是否可以混合使用 TypeModel 和属性方法,或者如果我选择仅使用 TypeModel 方法等,如何将未知类型成员作为字段添加到已知类型成员中),所以我需要我的情况的一个具体例子。
例如,我像这样声明 TypeModel:
RuntimeTypeModel.Default.Add(typeof(Vector3), false).Add(1, "x").Add(2, "y").Add(3, "z");
RuntimeTypeModel.Default.Add(typeof(SerializableTestClass), false).Add(1, "_x").Add(2, "_y").Add(3, "_coords");
Run Code Online (Sandbox Code Playgroud)
序列化/反序列化:
if (GUILayout.Button("Serialize")) {
SerializableTestClass testClass = new SerializableTestClass();
testClass.changeMembers();
RuntimeTypeModel.Default.Serialize(_serializedObject, testClass);
}
if (GUILayout.Button("Deserialize")) {
SerializableTestClass test = (SerializableTestClass) RuntimeTypeModel.Default.Deserialize(_serializedObject, null, typeof(SerializableTestClass));
Debug.Log("Deserialized object: " …Run Code Online (Sandbox Code Playgroud) 我有一个家长班,我想要有很多扁平的孩子。这意味着一个类固有 10 个或更多不同的类。
\n\n这是我所拥有的。
\n\n基类:
\n\n[ProtoContract]\n[ProtoInclude(500, typeof(Message1Send))]\n[ProtoInclude(501, typeof(Message2Send))]\npublic class MessageBase\n{\n [ProtoMember(1)]\n public string Topic {get;set;}\n [ProtoMember(2)]\n public string Action { get; set; } \n}\nRun Code Online (Sandbox Code Playgroud)\n\n许多子课程中的 2 个:
\n\n[ProtoContract] \npublic class Message1Send : MessageBase\n{ \n [ProtoMember(1)]\n public string Property1 { get; set; }\n}\n\n[ProtoContract] \npublic class Message2Send : MessageBase\n{ \n [ProtoMember(1)]\n public string Property1 { get; set; }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我希望能够告诉子对象我是基类的一部分。
\n\n我不知道如何达到我的基类如下所示的地步:
\n\n[ProtoContract]\n[ProtoInclude(500, typeof(Message1Send))]\n[ProtoInclude(501, typeof(Message2Send))]\n[ProtoInclude(502, typeof(Message3Send))]\n[ProtoInclude(503, typeof(Message4Send))]\n[ProtoInclude(504, typeof(Message5Send))]\n[ProtoInclude(505, typeof(Message6Send))]\n[ProtoInclude(506, typeof(Message7Send))]\n[ProtoInclude(507, typeof(Message8Send))]\n[ProtoInclude(508, typeof(Message9Send))]\n[ProtoInclude(509, typeof(Message10Send))]\npublic class MessageBase\n{\n [ProtoMember(1)]\n …Run Code Online (Sandbox Code Playgroud) 在我的项目中,我不仅需要时间,还需要有关 UTC 偏移量的信息。因此我考虑使用DateTimeOffset类。
我没有做任何魔法,只是声明了struct包含shortfor offset 和longfor ticks (与 中相同DateTimeOffset) - 当然还定义了ProtoContract和ProtoMember属性。
但是:即使这个值没有初始化(两个字段都为零),线路上还有 2 个额外的字节(我用 a 进行了交叉检查class)!
我尝试继承DefaultValueAttribute并设置我的默认值 - 但也无济于事。
原因是 protobuf-net 检查按DefaultValueAttribute名称(在MetaType.ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute))。
if ((attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null)
{
object tmp;
if(attrib.TryGet("Value", out tmp)) defaultValue = tmp;
}
Run Code Online (Sandbox Code Playgroud)
但即使我改变了这一点,我也会抱怨例外DefaultValueDecorator.Read(Compiler.CompilerContext ctx, Compiler.CodeLabel label):
default:
throw new NotSupportedException("Type cannot be represented as …Run Code Online (Sandbox Code Playgroud) protogen.exeproto2为类型的消息字段生成此模式long:
private long _Count = default(long);
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"Count", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
[global::System.ComponentModel.DefaultValue(default(long))]
public long Count
{
get { return _Count; }
set { _Count = value; }
}
Run Code Online (Sandbox Code Playgroud)
但由于proto2不包含日期时间类型(并且protobuf-net不支持proto3包含google.protobuf.Timestamp),因此不清楚如何DateTime在手动编码的 C# proto 对象中表示。
这可能是错误的:
private DateTime _When = DateTime.MinValue;
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"When", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(DateTime.MinValue)]
public DateTime When
{
get { return _When; }
set { _When = value; }
} …Run Code Online (Sandbox Code Playgroud) 我有一个名为 Person.proto 的简单原型文件,其中包含以下内容。我不明白我错过了什么。
syntax = "proto2";
message Person{
optional string name = 1;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用的命令是
Protoc Person.proto --csharp_out=C:\Users\Owner\.nuget\packages\google.protocolbuffers\2.4.1.555\tools Person.cs
Run Code Online (Sandbox Code Playgroud)
人物.cs
public class Person
{
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的项目创建 gRPC 服务。我有一堂课:
public class ServiceObject
{
public bool IsValuable { get; set; }
public bool IsValid { get; set; }
public object Result { get; set; }
public string ResultCode { get; set; }
public Exception Exception { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想从服务接收的对象。
我已经从谷歌阅读了 gRPC/Protobuf 的规范,但不明白如何做到这一点 - 我不知道如何传递object像Exception.
其他问题。让我们学习LocationGoogleApi C# 库中的类。
public class Location
{
public Location();
public Location(string address);
public Location(double latitude, double longitude);
[JsonProperty("lat")]
public double Latitude { get; set; } …Run Code Online (Sandbox Code Playgroud) protobuf-net ×10
c# ×9
.net ×3
asp.net-core ×1
build ×1
datetime ×1
grpc ×1
inheritance ×1
timestamp ×1