gpt4 book ai didi

.net - 使用 protobuf-net 代理有什么问题?

转载 作者:行者123 更新时间:2023-12-02 04:09:14 28 4
gpt4 key购买 nike

使用 protobuf-net v2 观察这个简单的代码:

  interface IObject { }

[ProtoContract]
class Person : IObject
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3, AsReference = true)]
public Address Address { get; set; }
}
[ProtoContract]
class Address : IObject
{
[ProtoMember(1)]
public string Line1 { get; set; }
[ProtoMember(2)]
public string Line2 { get; set; }
}

class Command
{
public List<IObject> Objects { get; set; }
}

internal interface ICommandSurrogatePiece
{
IEnumerable<IObject> Objects { get; set; }
}

[ProtoContract]
class CommandSurrogatePiece<T> : ICommandSurrogatePiece
where T : class, IObject
{
[ProtoMember(1)]
public List<T> Objects { get; set; }

#region ICommandSurrogatePiece Members

IEnumerable<IObject> ICommandSurrogatePiece.Objects
{
get { return Objects; }
set { Objects = value as List<T> ?? value.Cast<T>().ToList(); }
}

#endregion
}

[ProtoContract]
class CommandSurrogate
{
public static implicit operator Command(CommandSurrogate surrogate)
{
var objects = surrogate.Pieces.SelectMany(c => c.Objects).ToList();
return new Command { Objects = objects };
}
public static implicit operator CommandSurrogate(Command cmd)
{
var pieces = cmd.Objects.GroupBy(o => o.GetType(),
o => o, CreateCommandSurrogatePiece).ToList();
return new CommandSurrogate { Pieces = pieces };
}

private static ICommandSurrogatePiece CreateCommandSurrogatePiece(
Type type, IEnumerable<IObject> objects)
{
var piece = (ICommandSurrogatePiece)Activator.CreateInstance(
typeof(CommandSurrogatePiece<>).MakeGenericType(type));
piece.Objects = objects;
return piece;
}

[ProtoMember(1, DynamicType = true)]
public List<ICommandSurrogatePiece> Pieces { get; set; }
}

class Program
{
static void Main()
{
var person = new Person { Id = 12345, Name = "Fred", Address =
new Address { Line1 = "Flat 1", Line2 = "The Meadows" } };
var person2 = new Person { Id = 2345, Name = "Fred kaka", Address =
new Address { Line1 = "Flat 12", Line2 = "The Meadows kuku" } };
var address =
new Address { Line1 = "Flat 2", Line2 = "The Meadows Double" };
var address2 =
new Address { Line1 = "Flat 2 bubub",
Line2 = "The Meadows Double kuku" };

var model = TypeModel.Create();
model.Add(typeof(CommandSurrogate), true);
model.Add(typeof(Command), false).SetSurrogate(typeof(CommandSurrogate));
var command = new Command { Objects =
new List<IObject> { person, address, person2, address2 } };
var command2 = (Command)(CommandSurrogate)command;
var command3 = Serializer.DeepClone(command);
}
}

最后一行失败并出现异常。我究竟做错了什么?
谢谢。

编辑
System.InvalidOperationException occurred
Message=Type is not expected, and no contract can be inferred: HelloProtoBuf.Command
Source=protobuf-net
StackTrace:
at ProtoBuf.Meta.TypeModel.ThrowUnexpectedType(Type type)
InnerException:

编辑2

我稍微修改了代码以修复代理代码,但这不会影响问题 - 它仍然存在。

编辑3

我知道 command2command包含不同顺序的对象。这在我的场景中是可以接受的。我期待 command3相当于 command2 ,但由于某种原因,我得到了那个异常(exception)。

最佳答案

哦,乍一看,这比我敢希望的要容易。如果您使用自定义模型,则需要使用 model 上公开的方法. v1 API(即 Serializer.blah )现在只是对 RuntimeTypeModel.Default 的间接引用。 .

尝试:

var command3 = (Command)model.DeepClone(command);

另请注意,新创建的对象可能以 null 的形式出现。 - 在我的本地复制中,我添加了:
if (cmd == null) return null;

给运营商。当我感觉不那么难看时,我会看一看,看看库确保非空是否有意义。

关于.net - 使用 protobuf-net 代理有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6093957/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com