如何在dotnet / C#中使用MessageDescriptor创建一个protobuf消息实例

4

背景: 使用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就足够了(即慢一些的性能在我的特定应用程序/上下文中不是一个重要问题),但我想知道是否有更好/推荐的方法。

1个回答

4
很不幸,目前我看不到相关的内容。
在内部(例如在JsonParser中),我们调用messageDescriptor.Parser.CreateTemplate(),但是CreateTemplate()是一个内部方法。
我想你可以调用:
var message = messageDescriptor.Parser.ParseFrom(ByteString.Empty);

这样可以避免反射,我相信它会有效,但是它看起来比较丑陋。作为替代方案值得考虑...


好的,谢谢Jon。这是要加入到未来版本中的吗?还是这是某个更大的设计决策的结果? - redcalx
好的,我会评估ParseFrom()方法的性能,如果它明显更好,我可能会使用它。只要适当地进行注释,我认为我可以忍受这一行丑陋的代码。 - redcalx
1
没有我能记得的特定设计决策。随意提交功能请求 :) (您可以在“MessageDescriptor”上潜在地隐藏丑陋的行;) - Jon Skeet
1
FYI,我进行了一些基本的性能测试,ParseFrom 比 CreateInstance() 稍微快一点(在 dotnet core 2.2 上我看到大约是18M/sec vs 16M/sec)。 - redcalx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接