【问题标题】:How to create a protobuf Message instance given a MessageDescriptor (in dotnet / C#)如何在给定 MessageDescriptor 的情况下创建 protobuf Message 实例(在 dotnet / C# 中)
【发布时间】:2018-12-17 17:50:20
【问题描述】:

上下文:使用 Google.Protobuf 3.6.1 的 C#/dotnet 控制台应用程序

我想仅在给定 MessageDescriptor 的情况下实例化一个新的 protobuf 消息对象,即消息类型在编译时是未知的。

一种方法是:

IMessage message = (IMessage)Activator.CreateInstance(messageDescriptor.ClrType);

从这里开始,似乎支持消息对象的运行时操作,例如

FieldDescriptor fieldDescriptor = messageDescriptor.Fields[0];
fieldDescriptor.Accessor.SetValue(message, 123)

快速搜索表明 CreateInstance(Type) 的效率不如编译时间new Foo(),所以我想知道是否有我缺少的内置支持,例如我希望得到类似的东西:

var msg = messageDescriptor.CreateMessage()

var msg = MessageBuilder.Create(messageDescriptor)

Activator.CreateInstance 足以满足我的需求(即,在我的特定应用程序/上下文中,较慢的性能并不是一个重大问题),但我想知道我是否缺少更好/推荐的方法。

【问题讨论】:

    标签: c# .net protocol-buffers


    【解决方案1】:

    不幸的是,就我目前所见,没有。

    在内部(例如在 JsonParser 中)我们调用 messageDescriptor.Parser.CreateTemplate(),但 CreateTemplate() 是一个内部方法。

    我想你可以打电话:

    var message = messageDescriptor.Parser.ParseFrom(ByteString.Empty);
    

    这样可以避免反射,而且我很有信心它会起作用,但它相当难看。值得考虑作为替代方案...

    【讨论】:

    • 好的,谢谢乔恩。可能会在未来的版本中添加一些东西?还是这是某个更大的设计决策的结果?
    • 好的,我将评估 ParseFrom() 方法的性能,如果它明显更好,我可能会使用它。我认为只要注释得当,我就可以忍受一行丑陋的代码。
    • 我不记得有什么特别的设计决定。随意提交功能请求:)(您可以将丑行隐藏在MessageDescriptor 上的扩展方法后面;)
    • 仅供参考,我进行了一些基本的性能测试,ParseFrom 比 CreateInstance() 略快(我在 dotnet core 2.2 上看到大约 18M/秒 vs 16M/秒)。
    猜你喜欢
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2011-03-30
    相关资源
    最近更新 更多