{"id":479335,"date":"2026-05-11T16:15:35","date_gmt":"2026-05-11T16:15:35","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=479335"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=479335","title":{"rendered":"\u041f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 gRPC"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0422\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0430 gRPC &#8212; \u0438 \u0434\u0443\u043c\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0432\u0437\u044f\u043b protobuf, \u043e\u043f\u0438\u0441\u0430\u043b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e\u00ab? \u0422\u0430\u043a \u0434\u0443\u043c\u0430\u043b \u0438 \u044f. \u0414\u043e\u00a0\u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441\u00a0\u0442\u0435\u043c, \u0447\u0442\u043e\u00a0decimal \u0432\u00a0protobuf \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435\u00a0\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, nullable int \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043d\u0435\u0447\u0442\u043e \u0441\u00a0\u0444\u043b\u0430\u0433\u043e\u043c HasValue \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0433\u043e int?, \u0430\u00a0\u0434\u0432\u0430 enum \u0432\u00a0\u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0443\u0431\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438\u0437\u2011\u0437\u0430 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0430 \u0438\u043c\u0451\u043d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439\u00a0\u2014 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043a\u0430\u0436\u0435\u0442 \u0442\u0435\u0431\u0435 \u043e\u0431\u00a0\u044d\u0442\u043e\u043c \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u00a0\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e.\u00bb<\/p>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f\u00a0\u2014 \u0432\u044b\u0436\u0438\u043c\u043a\u0430 \u0431\u043e\u043b\u0438 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u0438\u0437\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u00a0\u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0443 REST \u0438 WCF \u043d\u0430\u00a0gRPC, \u0433\u0434\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439\u00a0\u0431\u044b\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043e\u0442\u043d\u0438: \u0441\u00a0\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u043c\u0438, decimal, DateTime, object, nullable \u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438\u0437\u00a0\u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0438\u043c\u0451\u043d. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0434\u044b\u00a0\u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u043f\u043e\u0434\u00a0protoc v34.1\u00a0\u0438.NET 10.<\/p>\n<h2>TL;DR;<\/h2>\n<ul>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439.proto\u2011\u0444\u0430\u0439\u043b\u044b, \u0430\u00a0\u043d\u0435\u00a0protobuf\u2011net; \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 = \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b + package<\/p>\n<\/li>\n<li>\n<p>Nullable \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432\u00a0\u2014 optional int \u043d\u0435\u00a0\u0434\u0430\u0451\u0442 int?, \u043d\u0443\u0436\u043d\u044b google\/protobuf\/wrappers.proto<\/p>\n<\/li>\n<li>\n<p>Nullable \u0434\u043b\u044f\u00a0\u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438 enum\u00a0\u2014 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435\u00a0\u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u0442 optional \u0438 \u0431\u0435\u0437\u00a0\u043d\u0435\u0433\u043e; enum \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 HasXxx\/ClearXxx \u0432\u043c\u0435\u0441\u0442\u043e Nullable&lt;T&gt;<\/p>\n<\/li>\n<li>\n<p>Decimal\u00a0\u2014 \u0442\u0438\u043f\u0430 \u043d\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 DecimalValue \u043f\u043e\u00a0\u0440\u0435\u0446\u0435\u043f\u0442\u0443 Microsoft \u0438\u043b\u0438\u00a0money.proto; \u0438\u0437\u0431\u0435\u0433\u0430\u0439 implicit operator<\/p>\n<\/li>\n<li>\n<p>DateTime\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 google\/protobuf\/timestamp.proto; DateTime \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e.ToUniversalTime()<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u00a0\u2014 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439; \u0434\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430: \u043e\u0442\u00a0\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c (\u0447\u0438\u0442\u0430\u0435\u043c\u0435\u0435) \u0438\u043b\u0438\u00a0\u043e\u0442\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u00a0\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c (\u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c)<\/p>\n<\/li>\n<li>\n<p>\u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438\u00a0\u2014 \u0442\u0440\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438: \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435), oneof (\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441), google.protobuf.Any (\u0433\u0438\u0431\u043a\u043e, \u043d\u043e\u00a0\u0431\u0435\u0437\u00a0type safety)<\/p>\n<\/li>\n<li>\n<p>Enum\u00a0\u2014 \u0438\u043c\u0435\u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u044b\u00a0\u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b \u0432\u00a0\u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430; \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043e\u00a0\u0431\u044b\u0442\u044c 0; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &lt;\u0418\u043c\u044fEnum&gt;_&lt;\u0418\u043c\u044f\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f&gt;<\/p>\n<\/li>\n<li>\n<p>Object\u00a0\u2014 \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u0441\u0430\u0434\u043d\u0438\u043a\u0430 \u0430\u043f\u043e\u043a\u0430\u043b\u0438\u043f\u0441\u0438\u0441\u0430: Any, oneof, google.protobuf.Value\/Struct, \u0440\u0443\u0447\u043d\u0430\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u00a0bytes\/string<\/p>\n<\/li>\n<\/ul>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432: protobuf \u0438\u043b\u0438 \u043d\u0435 protobuf?<\/h2>\n<p><strong>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/strong><\/p>\n<p>gRPC \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 protobuf. \u042f \u0441\u0435\u0439\u0447\u0430\u0441 \u0433\u043e\u0432\u043e\u0440\u044e \u043f\u0440\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 protobuf-net. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043c\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b\u0438 protobuf \u0438 protobuf-net (.NET \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432).<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0441\u0442\u0440\u043e\u0433\u043e\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c contract-first, protobuf-net \u0442\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 protobuf \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0447\u0442\u043e\u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u042f\u041f.<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 proto-\u0444\u0430\u0439\u043b\u044b.<\/p>\n<h2>\u041c\u043d\u043e\u0433\u043e \u0138\u043b\u0430\u0441\u0441\u043e\u0432 \u0432 protobuf<\/h2>\n<p>\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 Grpc, \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0431\u044b\u043b\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u0435\u0440\u0435\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u043e \u0437\u0430 100-\u043d\u044e. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u0441\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c proto-\u0444\u0430\u0439\u043b\u0435, \u043d\u043e \u044d\u0442\u043e \u0434\u043b\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0434\u043e\u043b\u0433\u043e, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432 \u0438\u043c\u0435\u043d. \u0417\u0430\u0442\u0435\u043c \u044f \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0441 message \u043f\u043e \u043d\u0435\u0439\u0441\u043f\u0435\u0439\u0441\u0430\u043c\/\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\/\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u043a\u0430\u043a-\u0442\u043e, \u043d\u043e \u043d\u0438 \u043a \u0447\u0435\u043c\u0443 \u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u043b\u043e. <\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u044f<\/strong><\/p>\n<ol>\n<li>\n<p> \u041e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 = \u043e\u0434\u0438\u043d proto-\u0444\u0430\u0439\u043b (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f) + \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>package<\/code> (\u0430\u043d\u0430\u043b\u043e\u0433\u00a0namespace\u00a0\u0432 \u043c\u0438\u0440\u0435 protobuf) \u0434\u043b\u044f \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043c\u0451\u043d<\/p>\n<\/li>\n<li>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u043e \u043e\u0431\u044a\u0435\u043c\u0443 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u0430\u043a \u0443 \u043d\u0430\u0441, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u0438\u0445 \u043f\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0432 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/protobuf.dev\/best-practices\/1-1-1\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a><\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c proto-\u0444\u0430\u0439\u043b\u044b \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043f\u043e \u043f\u0430\u043f\u043a\u0430\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0Protos\/Models\/\u00a0\u0438\u00a0Protos\/Services\/\u00a0), \u0443 \u0432\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 <code>.csproj<\/code>:<\/p>\n<pre><code class=\"xml\">&lt;ItemGroup&gt;    &lt;!-- \u041c\u043e\u0434\u0435\u043b\u0438: \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0438 \u043a Server, \u043d\u0438 \u043a Client --&gt;  &lt;Protobuf Include=\"Protos\\Models\\**\\*.proto\"&gt;    &lt;GrpcServices&gt;None&lt;\/GrpcServices&gt;    &lt;Access&gt;Public&lt;\/Access&gt;    &lt;ProtoCompile&gt;True&lt;\/ProtoCompile&gt;    &lt;ProtoRoot&gt;Protos&lt;\/ProtoRoot&gt; &lt;!-- \u041a\u043e\u0440\u0435\u043d\u044c \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0430\u0448\u0438 import --&gt;  &lt;\/Protobuf&gt;    &lt;!-- \u0421\u0435\u0440\u0432\u0438\u0441\u044b --&gt;  &lt;Protobuf Include=\"Protos\\Services\\**\\*.proto\"&gt;    &lt;GrpcServices&gt;Server&lt;\/GrpcServices&gt; &lt;!-- Both - \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 --&gt;    &lt;Access&gt;Public&lt;\/Access&gt;    &lt;ProtoCompile&gt;True&lt;\/ProtoCompile&gt;    &lt;ProtoRoot&gt;Protos&lt;\/ProtoRoot&gt;    &lt;CompileOutputs&gt;True&lt;\/CompileOutputs&gt;  &lt;\/Protobuf&gt;  &lt;\/ItemGroup&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u0430\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e Grpc.Tools <a href=\"https:\/\/chromium.googlesource.com\/external\/github.com\/grpc\/grpc\/+\/HEAD\/src\/csharp\/BUILD-INTEGRATION.md\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a><\/p>\n<h2>Nullable \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>int32 SomeDataOptional<\/code>, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e \u043a\u0430\u043a <code>optional<\/code>, \u0442\u043e \u0432\u00a0\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 <code>int? SomeDataOptional { get; set; }<\/code>. \u0411\u0443\u0434\u0435\u0442 <code>int SomeDataOptional { get; set; }<\/code>, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>HasSomeData<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0431\u044b\u043b\u043e \u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u043b\u0438\u00a0\u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a\u00a0\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e\u00a0&#8212; \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u00a0\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e &#8212; \u044d\u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0439 \u0442\u0438\u043f. \u041a\u043e\u0441\u0442\u044b\u043b\u044c, \u0447\u0442\u043e\u00a0\u0441\u043a\u0430\u0437\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2f0\/866\/e2c\/2f0866e2cbae9e1a6593a24daccf71a8.png\" width=\"2628\" height=\"1664\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/2f0\/866\/e2c\/2f0866e2cbae9e1a6593a24daccf71a8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2f0\/866\/e2c\/2f0866e2cbae9e1a6593a24daccf71a8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong>\u00a0&#8212; <a href=\"https:\/\/github.com\/protocolbuffers\/protobuf\/blob\/main\/src\/google\/protobuf\/wrappers.proto\" rel=\"noopener noreferrer nofollow\"><code>google\/protobuf\/wrappers.proto<\/code><\/a>. \u041f\u0440\u0438\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u0431\u0435\u0440\u0442\u043e\u043a (wrappers) \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e: nullable\u2011\u0442\u0438\u043f \u0432\u00a0\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3c3\/70d\/221\/3c370d22150d91a4a449e914787bed0a.png\" width=\"2230\" height=\"756\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3c3\/70d\/221\/3c370d22150d91a4a449e914787bed0a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3c3\/70d\/221\/3c370d22150d91a4a449e914787bed0a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c <strong>\u0441\u0432\u043e\u0438<\/strong> \u043e\u0431\u0435\u0440\u0442\u043a\u0438\u00a0&#8212; \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u0435\u0439, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0439 \u0442\u0438\u043f. \u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435\u00a0\u0442\u043e, \u0447\u0442\u043e\u00a0\u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0438\u0436\u0435.<\/p>\n<h2>Nullable \u0434\u043b\u044f \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/h2>\n<p>\u0414\u043b\u044f \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445\u00a0message\u00a0) \u0138\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0439 \u043c\u0435\u0436\u0434\u0443\u00a0optional\u00a0\u0438 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e &#8212; \u043e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0434\u0430\u0434\u0443\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0431\u0435\u0437\u00a0<code>?<\/code>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/126\/2ec\/0a5\/1262ec0a5dd7f2cbda9f9e6409a40a1c.png\" alt=\"\u041d\u0430\u0439\u0434\u0438 10 \u043e\u0442\u043b\u0438\u0447\u0438\u0439\" title=\"\u041d\u0430\u0439\u0434\u0438 10 \u043e\u0442\u043b\u0438\u0447\u0438\u0439\" width=\"2052\" height=\"1190\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/126\/2ec\/0a5\/1262ec0a5dd7f2cbda9f9e6409a40a1c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/126\/2ec\/0a5\/1262ec0a5dd7f2cbda9f9e6409a40a1c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041d\u0430\u0439\u0434\u0438 10 \u043e\u0442\u043b\u0438\u0447\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c optional \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c null. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445.<\/p>\n<h2>Nullable \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 (enum)<\/h2>\n<p>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u043c \u0442\u0438\u043f\u0430\u043c:\u00a0optional enum\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e HasXXX \u0438 \u043c\u0435\u0442\u043e\u0434\u00a0ClearXXX\u00a0, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435\u00a0Nullable&lt;EnumType&gt;.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4c1\/3d1\/41b\/4c13d141b4237fd06f18dbff73eed3a4.png\" width=\"2550\" height=\"1600\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/4c1\/3d1\/41b\/4c13d141b4237fd06f18dbff73eed3a4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4c1\/3d1\/41b\/4c13d141b4237fd06f18dbff73eed3a4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\"><strong>\u041f\u043e\u0434\u0445\u043e\u0434<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\"><code>optional EnumType field<\/code><\/p>\n<\/td>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\">EnumType\u00a0+\u00a0HasXxx\u00a0\/\u00a0ClearXxx<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"168\" width=\"168\">\n<p>\u041e\u0431\u0451\u0440\u0442\u0138\u0430 <\/p>\n<p>message EnumWrapper { <br \/>   EnumType value = 1; <br \/>}\u00a0<\/p>\n<\/td>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\">\u0414\u0430, \u044d\u0442\u043e \u043a\u0430\u043a \u0441 \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, \u043d\u043e \u0438\u043d\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b. \u0422\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c optional \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0430\u043a\u043e\u0433\u043e wrapper, \u0441\u043b\u0435\u0434\u0443\u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0435 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435. <\/p>\n<h2>Decimal<\/h2>\n<p>\u0412 protobuf \u043d\u0435\u0442 \u0442\u0438\u043f\u0430\u00a0decimal. \u041f\u0440\u044f\u043c\u044b\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b &#8212;\u00a0double\u00a0\u0438\u00a0float\u00a0, \u043d\u043e \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0434\u043b\u044f \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043f\u043e\u0442\u0435\u0440\u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/github.com\/googleapis\/googleapis\/blob\/master\/google\/type\/money.proto\" rel=\"noopener noreferrer nofollow\">google\/protobuf\/money.proto<\/a> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0443\u043c\u043c\u0443 \u0438 \u0432\u0430\u043b\u044e\u0442\u0443 (\u0441\u0442\u0440\u043e\u0138\u0430).<\/p>\n<\/li>\n<li>\n<p><strong>DecimalValue<\/strong>\u00a0\u043f\u043e \u0440\u0435\u0446\u0435\u043f\u0442\u0443\u00a0<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/grpc\/protobuf?view=aspnetcore-10.0#decimals\" rel=\"noopener noreferrer nofollow\">Microsoft<\/a><\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0412\u0430\u0436\u043d\u043e<\/strong>: \u0438\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435\u00a0implicit operator\u00a0\u0434\u043b\u044f \u0138\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438, \u0442\u0430\u0138 \u0138\u0430\u0138 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0138 NullReferenceException\u00a0\u043f\u0440\u0438\u00a0DecimalValue == null. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044f\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">public static class DecimalValueExtension{    private const decimal NanoFactor = 1_000_000_000;      public static decimal ToDecimal(this DecimalValue value)      =&gt; value.Units + value.Nanos \/ NanoFactor;      public static decimal? ToNullableDecimal(this DecimalValue? value)      =&gt; value is null ? null : value.ToDecimal();      public static DecimalValue ToDecimalValue(this decimal value)    {        var units = decimal.ToInt64(value);        var nanos = decimal.ToInt32((value - units) * NanoFactor);        return new DecimalValue { Units = units, Nanos = nanos };    }      public static DecimalValue? ToNullableDecimalValue(this decimal? value)      =&gt; value is null ? null : value.Value.ToDecimalValue();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>DateTime \u0438 DateTimeOffset<\/h2>\n<p>\u0412 protobuf \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u0442\u043e\u0439\/\u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c.<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u044d\u0442\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/github.com\/protocolbuffers\/protobuf\/blob\/main\/src\/google\/protobuf\/timestamp.proto\" rel=\"noopener noreferrer nofollow\">google\/protobuf\/timestamp.proto<\/a>, \u0434\u043b\u044f C# \u0443 \u043d\u0435\u0433\u043e \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f Timestamp: ToDateTime() \u0438 ToDateTimeOffset()<\/p>\n<\/li>\n<li>\n<p>\u0412 Timestamp:<\/p>\n<ul>\n<li>\n<p>\u0418\u0437 DateTime: \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c DateTime \u0432 Timestamp \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u043a UTC, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>ToUniversalTime()<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>ToTimestamp()<\/code><\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 DateTimeOffset: \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 <code>.ToTimestamp()<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e5e\/e67\/9b1\/e5ee679b1cd2c4ea14a1d94dbff406e9.png\" width=\"1866\" height=\"508\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e5e\/e67\/9b1\/e5ee679b1cd2c4ea14a1d94dbff406e9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e5e\/e67\/9b1\/e5ee679b1cd2c4ea14a1d94dbff406e9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u0138\u0442\u043d\u044b\u0435 \u0138\u043b\u0430\u0441\u0441\u044b<\/h2>\n<p>\u0412 protobuf \u043d\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f (\u0438 oneof, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435). \u041c\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435, \u043e\u0431\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0430 \u0432\u044b \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u043b\u0438? \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c, \u0438 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c, \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c &#8212; \u0434\u0430 \u0435\u0441\u0442\u044c \u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u043c\u0438\u043d\u0443\u0441\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f C#-\u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">[abstract] class Base{    public int Id { get; set; }}class User : Base{    public string Name { get; set; }}class UserAdditionalInfo : User{    public DateTimeOffset BDay { get; set; }}class Role : Base{    public int Priority { get; set; }    public string RoleName { get; set; }}class UseBaseClass{    public Base Base { get; set; }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)<\/strong><\/p>\n<pre><code class=\"go\">syntax = \"proto3\";message Base {    int32 id = 1;}message User {    Base base = 1;    string name = 2;}message UserAdditionalInfo {    User base = 1;    google.protobuf.Timestamp b_day = 2;}message Role {    Base base = 1;    int32 priority = 2;    string role_name = 3;}\/\/ \u041d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\/\u043a\u043b\u0430\u0441\u0441, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0442\u0438\u043f\u043e\u043cmessage BaseChildrens {    oneof type {        User user = 1;        UserAdditionalInfo user_additional_info = 2;        Role role = 3;    }}message UseBaseClass {    BaseChildrens base = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c &#8212; \u0435\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0438\u043b\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 message, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434-\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434-\u043f\u043e\u0434-&#8230;<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0445 \u0138 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c<\/strong><\/p>\n<pre><code class=\"go\">syntax = \"proto3\";\/\/ \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439\/\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043emessage Base {    int32 id = 1;    oneof child {        User user = 2;        Role role = 3;    }}message User {  string name = 1;    oneof child {        UserAdditionalInfo user_additional_info = 2;    }}message UserAdditionalInfo {    google.protobuf.Timestamp b_day = 1;}message Role {    int32 priority = 1;    string role_name = 2;}message UseBaseClass {    Base base = 1; \/\/ \u0432\u0441\u0435 \u0442\u0430\u043a \u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"209\" width=\"209\">\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"265\" width=\"265\">\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u2192 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0435 \u2192 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"209\" width=\"209\">\n<p>\u0427\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438<\/p>\n<\/td>\n<td data-colwidth=\"265\" width=\"265\">\n<p align=\"left\">\u2705 \u041b\u0443\u0447\u0448\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c \u0425\u0443\u0436\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"209\" width=\"209\">\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0138\u043b\u0430\u0441\u0441\u043e\u043c<\/p>\n<\/td>\n<td data-colwidth=\"265\" width=\"265\">\n<p align=\"left\">\u26a0\ufe0f \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f BaseChildrens, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705 \u0423\u0434\u043e\u0431\u043d\u043e, \u0443\u0436\u0435 \u0432\u0441\u0435 \u0435\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>Generic, aka \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/h2>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u043f\u0438\u0441\u043a\u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 generic<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0434\u043d\u0435\u0432\u043d\u0438\u043a, \u043c\u043d\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u043b\u043e\u0432 \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u043b\u044c \u0438 \u0443\u043d\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0438\u0441\u043f\u044b\u0442\u0430\u043b \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043c\u043e\u044f \u0436\u0438\u0437\u043d\u044c \u043f\u043e\u043b\u043e\u043c\u0430\u043d\u0430 \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430&#8230;<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u043c\u0435\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 BaseEntity, \u0432 \u043a\u043e\u0434\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441 <u>\u0442\u0440\u0435\u043c\u044f<\/u> \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438. \u0415\u0441\u0442\u044c \u0442\u0440\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438, \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0439 \u0442\u0435\u043c\u043d\u043e\u0439 \u043b\u043e\u0448\u0430\u0434\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>C#-\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u0138<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">class BaseEntity&lt;T&gt;{    public T Id { get; set; }}class User : BaseEntity&lt;int&gt;{    \/\/ ... }class Role : BaseEntity&lt;long&gt;{     \/\/ ... }class BaseEntityWrapper{    public BaseEntity&lt;string&gt; BaseEntity { get; set; }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)<\/strong><\/p>\n<p><span class=\"habrahidden\">\u0417\u0430\u0434\u0430\u0439 \u0441\u0435\u0431\u0435 \u0432\u043e\u043f\u0440\u043e\u0441, \u0442\u044b \u0437\u043d\u0430\u0435\u0448\u044c \u0432\u043e \u0447\u0442\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438?<\/span><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 generic. \u0414\u0430, \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u043d\u043e, \u0434\u0430, \u044d\u0442\u043e \u0442\u044f\u0436\u0435\u043b\u043e, \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435 \u043a \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044e.<\/p>\n<pre><code class=\"go\">syntax = \"proto3\";message BaseEntity_Int {    int32 id = 1;}message BaseEntity_Long {    int64 id = 1;}message BaseEntity_String {    string id = 1;}message User {    BaseEntity_Int base = 1; \/\/ \u043f\u043e\u0434\u0445\u043e\u0434 \"\u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\"}message Role {    BaseEntity_Long base = 1;}message BaseEntityWrapper {    BaseEntity_String base_entity = 1; \/\/ \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 (oneof)<\/strong><\/p>\n<pre><code class=\"go\">message BaseEntity {    oneof id {        int32  id_int32  = 1;        int64  id_int64  = 2;        string id_string = 3;    }}message BaseEntityWrapper {    BaseEntity base_entity = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 oneof \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"cs\">var proto = new BaseEntity();if (entity is BaseEntity&lt;int&gt; intEntity)    proto.IdInt32 = intEntity.Id;else if (entity is BaseEntity&lt;long&gt; longEntity)    proto.IdInt64 = longEntity.Id;else if (entity is BaseEntity&lt;string&gt; strEntity)    proto.IdString = strEntity.Id;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21163: \u043f\u043e\u043b\u043d\u0430\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u043a\u0430 (google.protobuf.Any)<\/strong><\/p>\n<p>Any \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0442\u0438\u043f, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 object, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 <a href=\"https:\/\/protobuf.dev\/programming-guides\/proto3\/#any\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<pre><code class=\"cs\">import \"google\/protobuf\/any.proto\";message BaseEntityWrapper {    google.protobuf.Any base_entity = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u0430\u0434\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0438 <code>Any.Pack<\/code>, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u043e\u0439 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0438\u043f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043b\u0435\u0436\u0438\u0442 \u0432 \u043d\u0435\u043c.<\/p>\n<pre><code class=\"cs\">\/\/ Packvar userEntity = new UserEntity { Id = 42 };var wrapper = new BaseEntityWrapper{    BaseEntity = Any.Pack(userEntity)};\/\/ Unpackif (wrapper.BaseEntity.Is(UserEntity.Descriptor)){    var user = wrapper.BaseEntity.Unpack&lt;UserEntity&gt;();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\">\u041f\u043e\u0434\u0445\u043e\u0434<\/p>\n<\/td>\n<td data-colwidth=\"247\" width=\"247\">\n<p align=\"left\">Type Safety<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\">\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td data-colwidth=\"247\" width=\"247\">\n<p align=\"left\">\u2705 \u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u274c \u041d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\"><code>oneof<\/code><\/p>\n<\/td>\n<td data-colwidth=\"247\" width=\"247\">\n<p align=\"left\">\u26a0\ufe0f \u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u26a0\ufe0f \u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"246\" width=\"246\">\n<p align=\"left\"><code>Any<\/code><\/p>\n<\/td>\n<td data-colwidth=\"247\" width=\"247\">\n<p align=\"left\">\u274c \u041d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2705 \u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>Enum: \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043d\u0443\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p><strong>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u21161: \u0138\u043e\u043d\u0444\u043b\u0438\u0138\u0442 \u0438\u043c\u0451\u043d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/strong><\/p>\n<p>\u0412 protobuf \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f enum \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 C++ scoping rules &#8212; \u0438\u043c\u0435\u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043d\u0438\u0138\u0430\u043b\u044c\u043d\u044b \u0432 \u0440\u0430\u043c\u0138\u0430\u0445 \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u0138\u0435\u0442\u0430 (\u0444\u0430\u0439\u043b\u0430), \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u0138\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e enum. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<pre><code class=\"go\">syntax = \"proto3\";enum PositionTypes {    Up = 1;    Down = 2; \/\/ \u0437\u043b\u043e\u0434\u0435\u0439 \u2116 1 !!!    Both = 3;}enum GraphMovementTypes {    Upper = 0;    Down = 1; \/\/ \u0437\u043b\u043e\u0434\u0435\u0439 \u2116 2 !!! - \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f    None = 2;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<p>\u0418\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0443\u00a0&lt;\u0418\u043c\u044fEnum&gt;_&lt;\u0418\u043c\u044f\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f&gt;<\/p>\n<pre><code class=\"go\">syntax = \"proto3\";enum PositionTypes {    PositionTypes_Up = 0;    PositionTypes_Down = 10;    PositionTypes_Both = 20;}enum GraphMovementTypes {    GraphMovementTypes_Upper = 0;    GraphMovementTypes_Down = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0443 \u0443 \u0432\u0430\u0441 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f enum \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u0438 \u0441\u0430\u043c\u043e\u0433\u043e enum<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ea\/070\/333\/3ea0703335e4c563f18ef935b9b7526f.png\" width=\"1842\" height=\"736\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3ea\/070\/333\/3ea0703335e4c563f18ef935b9b7526f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ea\/070\/333\/3ea0703335e4c563f18ef935b9b7526f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0435 \u0442\u0430\u043a\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/protobuf.dev\/programming-guides\/proto3\/#enum\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u043b\u044f \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439.<\/p>\n<p><strong>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 2: enum \u0432 protobuf \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 0<\/strong><\/p>\n<p>\u041f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c protobuf3 \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 enum \u043e\u0431\u044f\u0437\u0430\u043d\u043e \u0431\u044b\u0442\u044c\u00a00. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0435 legacy-\u0138\u043e\u0434\u0430, \u0433\u0434\u0435 \u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 1, \u043d\u0435 \u0441\u043c\u0435\u0449\u0430\u0439\u0442\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f &#8212; \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 <code>&lt;\u0418\u043c\u044fEnum&gt;_Undefined = 0<\/code>.<\/p>\n<h2>Object<\/h2>\n<p>\u042f \u043d\u0430\u0448\u0435\u043b 4 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u0430, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u0434\u0435\u043c\u043e\u043d\u043e\u043c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u044f \u043f\u0440\u043e \u043d\u0438\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043d\u043e \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u043e\u0439 &#8212; \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0431\u0435\u043a\u0435\u043d\u0434\u0435 object \u043f\u043e\u043b\u0435 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u043e\u0441\u044c, \u043e\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e \u0438 \u0443\u0445\u043e\u0434\u0438\u043b\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043f\u0440\u0438\u043d\u044f\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0435\u0440\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 string.<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: <\/strong><code><strong>google.protobuf.Any<\/strong><\/code><\/p>\n<p>\u0414\u0430 \u0441\u043d\u043e\u0432\u0430 \u043e\u043d, \u044d\u0442\u043e \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u044f\u043c\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 object, \u043a\u043b\u0430\u0434\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0448\u044c.<\/p>\n<pre><code class=\"go\">import \"google\/protobuf\/any.proto\";message Container {    google.protobuf.Any value = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0443 \u0441 \u043d\u0438\u043c \u0432\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0432\u044b\u0448\u0435, \u043d\u043e \u0432\u043e\u0442 \u0432\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a \u0443\u0437\u043d\u0430\u0442\u044c \u0447\u0442\u043e \u0437\u0430 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u0448\u0435\u043b<\/p>\n<pre><code class=\"cs\">\/\/ Packvar container = new Container();container.Value = Any.Pack(new UserEntity { Id = 1 });\/\/ Unpack - \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0442\u0438\u043f \u0437\u0430\u0440\u0430\u043d\u0435\u0435if (container.Value.Is(UserEntity.Descriptor)){    var user = container.Value.Unpack&lt;UserEntity&gt;();}\/\/ Unpack - \u0447\u0435\u0440\u0435\u0437 type_url \u0435\u0441\u043b\u0438 \u0442\u0438\u043f \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043dvar typeUrl = container.Value.TypeUrl; \/\/ \"type.googleapis.com\/UserEntity\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438 \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u0441\u043e \u0441\u0445\u0435\u043c\u043e\u0439, \u0442\u043e\u0433\u0434\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0435\u0451 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: union \u0447\u0435\u0440\u0435\u0437 <\/strong><code><strong>oneof<\/strong><\/code><\/p>\n<p>\u041f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u0435\u0441\u043b\u0438 \u043d\u0430\u0431\u043e\u0440 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0437\u0430\u0440\u0430\u043d\u0435\u0435.<\/p>\n<pre><code class=\"go\">message DynamicValue {    oneof value {        int32   int_val    = 1;        int64   long_val   = 2;        double  double_val = 3;        string  str_val    = 4;        bool    bool_val   = 5;        bytes   bytes_val  = 6;    }}message Container {    DynamicValue value = 1;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"cs\">\/\/ \u0417\u0430\u043f\u0438\u0441\u044cvar val = new DynamicValue();val.StrVal = \"hello\";          \/\/ object str = \"hello\"val.IntVal = 42;               \/\/ object num = 42\/\/ \u0427\u0442\u0435\u043d\u0438\u0435var result = val.ValueCase switch{    DynamicValue.ValueOneofCase.StrVal    =&gt; (object)val.StrVal,    DynamicValue.ValueOneofCase.IntVal    =&gt; (object)val.IntVal,    DynamicValue.ValueOneofCase.DoubleVal =&gt; (object)val.DoubleVal,    _ =&gt; null};<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21163: JSON-\u043f\u043e\u0434\u043e\u0431\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <\/strong><code><strong>google.protobuf.Value<\/strong><\/code><\/p>\n<p>\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430\u043d\u0430\u043b\u043e\u0433\u00a0<code>JsonElement<\/code>. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442: <code>null<\/code>, <code>bool<\/code>, <code>double<\/code>, <code>string<\/code>, <code>list<\/code>, <code>struct (map)<\/code>.<\/p>\n<pre><code class=\"go\">import \"google\/protobuf\/struct.proto\";message Container {    google.protobuf.Value value  = 1;  \/\/ \u043b\u044e\u0431\u043e\u0439 \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u044b\u0439 \u0442\u0438\u043f    google.protobuf.Struct config = 2; \/\/ \u0430\u043d\u0430\u043b\u043e\u0433 Dictionary&lt;string, object&gt;    google.protobuf.ListValue tags = 3; \/\/ \u0430\u043d\u0430\u043b\u043e\u0433 List&lt;object&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"cs\">\/\/ Value \u2014 \u0441\u043a\u0430\u043b\u044f\u0440\u044bvar container = new Container();container.Value = Value.ForString(\"hello\");container.Value = Value.ForNumber(3.14);container.Value = Value.ForBool(true);container.Value = Value.ForNull();\/\/ Struct \u2014 \u043a\u0430\u043a Dictionary&lt;string, object&gt;container.Config = new Struct();container.Config.Fields[\"name\"]  = Value.ForString(\"Alice\");container.Config.Fields[\"age\"]   = Value.ForNumber(30);container.Config.Fields[\"roles\"] = Value.ForList(    Value.ForString(\"admin\"),    Value.ForString(\"user\"));\/\/ \u0427\u0442\u0435\u043d\u0438\u0435var kind = container.Value.KindCase;  \/\/ StringValue, NumberValue, etc.var name = container.Config.Fields[\"name\"].StringValue;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21164: \u0440\u0443\u0447\u043d\u0430\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f bytes \u0438\u043b\u0438 string<\/strong><\/p>\n<p>\u0422\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0435 \u0442\u0430\u043a, \u043a\u0430\u043a \u0432\u0430\u043c \u0443\u0434\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p><strong>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u041f\u043e\u0434\u0445\u043e\u0434<\/p>\n<\/td>\n<td data-colwidth=\"148\" width=\"148\">\n<p align=\"left\">\u0427\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">Type Safety<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">Any<\/p>\n<\/td>\n<td data-colwidth=\"148\" width=\"148\">\n<p align=\"left\">Protobuf-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">\u26a0\ufe0f\u00a0\u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u26a0\ufe0f\u00a0\u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u2705\u00a0\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">oneof<\/p>\n<\/td>\n<td data-colwidth=\"148\" width=\"148\">\n<p align=\"left\">\u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">\u2705\u00a0\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u2705\u00a0\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u274c\u00a0\u041d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">Value\/Struct<\/p>\n<\/td>\n<td data-colwidth=\"148\" width=\"148\">\n<p align=\"left\">JSON-\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">\u274c\u00a0\u041d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u26a0\ufe0f\u00a0\u0421\u0440\u0435\u0434\u043d\u044f\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u2705\u00a0\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">bytes\/string<\/p>\n<\/td>\n<td data-colwidth=\"148\" width=\"148\">\n<p align=\"left\">\u041b\u044e\u0431\u044b\u0435<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">\u274c\u00a0\u041d\u0438\u0437\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u2705\u00a0\u0412\u044b\u0441\u043e\u043a\u0430\u044f<\/p>\n<\/td>\n<td data-colwidth=\"168\" width=\"168\">\n<p align=\"left\">\u2705\u00a0\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432<\/h2>\n<ol>\n<li>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 Grpc.Tools: <a href=\"https:\/\/chromium.googlesource.com\/external\/github.com\/grpc\/grpc\/+\/HEAD\/src\/csharp\/BUILD-INTEGRATION.md\" rel=\"noopener noreferrer nofollow\">Protocol Buffers\/gRPC Codegen Integration Into .NET Build<\/a><\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 proto: <a href=\"https:\/\/protobuf.dev\/best-practices\/1-1-1\/\" rel=\"noopener noreferrer nofollow\">1-1-1 Best Practice<\/a><\/p>\n<\/li>\n<li>\n<p>\u041b\u0443\u0447\u0448\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 proto: <a href=\"https:\/\/protobuf.dev\/programming-guides\/dos-donts\/\" rel=\"noopener noreferrer nofollow\">Proto Best Practices<\/a> <\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u043a\u043e\u0434\u0430 protoc: <a href=\"https:\/\/protobuf.dev\/reference\/csharp\/csharp-generated\/\" rel=\"noopener noreferrer nofollow\">C# Generated Code Guide<\/a><\/p>\n<\/li>\n<li>\n<p>\u0422\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 C# \u0438 Proto: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/grpc\/protobuf?view=aspnetcore-10.0\" rel=\"noopener noreferrer nofollow\">Create Protobuf messages for .NET apps<\/a><\/p>\n<\/li>\n<\/ol>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1033838\/\">https:\/\/habr.com\/ru\/articles\/1033838\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0422\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0430 gRPC &#8212; \u0438 \u0434\u0443\u043c\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0432\u0437\u044f\u043b protobuf, \u043e\u043f\u0438\u0441\u0430\u043b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e\u00ab? \u0422\u0430\u043a \u0434\u0443\u043c\u0430\u043b \u0438 \u044f. \u0414\u043e\u00a0\u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441\u00a0\u0442\u0435\u043c, \u0447\u0442\u043e\u00a0decimal \u0432\u00a0protobuf \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435\u00a0\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, nullable int \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u00a0\u043d\u0435\u0447\u0442\u043e \u0441\u00a0\u0444\u043b\u0430\u0433\u043e\u043c HasValue \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0433\u043e int?, \u0430\u00a0\u0434\u0432\u0430 enum \u0432\u00a0\u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0443\u0431\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438\u0437\u2011\u0437\u0430 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0430 \u0438\u043c\u0451\u043d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439\u00a0\u2014 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043a\u0430\u0436\u0435\u0442 \u0442\u0435\u0431\u0435 \u043e\u0431\u00a0\u044d\u0442\u043e\u043c \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u00a0\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e.\u00bb\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f\u00a0\u2014 \u0432\u044b\u0436\u0438\u043c\u043a\u0430 \u0431\u043e\u043b\u0438 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u0438\u0437\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u00a0\u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0443 REST \u0438 WCF \u043d\u0430\u00a0gRPC, \u0433\u0434\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439\u00a0\u0431\u044b\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043e\u0442\u043d\u0438: \u0441\u00a0\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u043c\u0438, decimal, DateTime, object, nullable \u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438\u0437\u00a0\u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0438\u043c\u0451\u043d. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0434\u044b\u00a0\u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u043f\u043e\u0434\u00a0protoc v34.1\u00a0\u0438.NET 10.TL;DR;\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439.proto\u2011\u0444\u0430\u0439\u043b\u044b, \u0430\u00a0\u043d\u0435\u00a0protobuf\u2011net; \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 = \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b + packageNullable \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432\u00a0\u2014 optional int \u043d\u0435\u00a0\u0434\u0430\u0451\u0442 int?, \u043d\u0443\u0436\u043d\u044b google\/protobuf\/wrappers.protoNullable \u0434\u043b\u044f\u00a0\u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438 enum\u00a0\u2014 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435\u00a0\u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u0442 optional \u0438 \u0431\u0435\u0437\u00a0\u043d\u0435\u0433\u043e; enum \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 HasXxx\/ClearXxx \u0432\u043c\u0435\u0441\u0442\u043e Nullable&lt;T&gt;Decimal\u00a0\u2014 \u0442\u0438\u043f\u0430 \u043d\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 DecimalValue \u043f\u043e\u00a0\u0440\u0435\u0446\u0435\u043f\u0442\u0443 Microsoft \u0438\u043b\u0438\u00a0money.proto; \u0438\u0437\u0431\u0435\u0433\u0430\u0439 implicit operatorDateTime\u00a0\u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 google\/protobuf\/timestamp.proto; DateTime \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e.ToUniversalTime()\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u00a0\u2014 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439; \u0434\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430: \u043e\u0442\u00a0\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c (\u0447\u0438\u0442\u0430\u0435\u043c\u0435\u0435) \u0438\u043b\u0438\u00a0\u043e\u0442\u00a0\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u00a0\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c (\u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u0438\u00a0\u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0\u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c)\u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438\u00a0\u2014 \u0442\u0440\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438: \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435), oneof (\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441), google.protobuf.Any (\u0433\u0438\u0431\u043a\u043e, \u043d\u043e\u00a0\u0431\u0435\u0437\u00a0type safety)Enum\u00a0\u2014 \u0438\u043c\u0435\u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u044b\u00a0\u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b \u0432\u00a0\u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430; \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u043e\u00a0\u0431\u044b\u0442\u044c 0; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &lt;\u0418\u043c\u044fEnum&gt;_&lt;\u0418\u043c\u044f\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f&gt;Object\u00a0\u2014 \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u0441\u0430\u0434\u043d\u0438\u043a\u0430 \u0430\u043f\u043e\u043a\u0430\u043b\u0438\u043f\u0441\u0438\u0441\u0430: Any, oneof, google.protobuf.Value\/Struct, \u0440\u0443\u0447\u043d\u0430\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u00a0bytes\/string\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432: protobuf \u0438\u043b\u0438 \u043d\u0435 protobuf?\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430gRPC \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 protobuf. \u042f \u0441\u0435\u0439\u0447\u0430\u0441 \u0433\u043e\u0432\u043e\u0440\u044e \u043f\u0440\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 protobuf-net. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043c\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b\u0438 protobuf \u0438 protobuf-net (.NET \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432).\u0423 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0441\u0442\u0440\u043e\u0433\u043e\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c contract-first, protobuf-net \u0442\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 protobuf \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0447\u0442\u043e\u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u042f\u041f.\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 proto-\u0444\u0430\u0439\u043b\u044b.\u041c\u043d\u043e\u0433\u043e \u0138\u043b\u0430\u0441\u0441\u043e\u0432 \u0432 protobuf\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 Grpc, \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0431\u044b\u043b\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u0435\u0440\u0435\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u043e \u0437\u0430 100-\u043d\u044e. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u0441\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c proto-\u0444\u0430\u0439\u043b\u0435, \u043d\u043e \u044d\u0442\u043e \u0434\u043b\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0434\u043e\u043b\u0433\u043e, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432 \u0438\u043c\u0435\u043d. \u0417\u0430\u0442\u0435\u043c \u044f \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0441 message \u043f\u043e \u043d\u0435\u0439\u0441\u043f\u0435\u0439\u0441\u0430\u043c\/\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\/\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u043a\u0430\u043a-\u0442\u043e, \u043d\u043e \u043d\u0438 \u043a \u0447\u0435\u043c\u0443 \u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u043b\u043e. \u0420\u0435\u0448\u0435\u043d\u0438\u044f \u041e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 = \u043e\u0434\u0438\u043d proto-\u0444\u0430\u0439\u043b (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f) + \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c package (\u0430\u043d\u0430\u043b\u043e\u0433\u00a0namespace\u00a0\u0432 \u043c\u0438\u0440\u0435 protobuf) \u0434\u043b\u044f \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043c\u0451\u043d\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u043e \u043e\u0431\u044a\u0435\u043c\u0443 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u0430\u043a \u0443 \u043d\u0430\u0441, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u0438\u0445 \u043f\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0432 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442\u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c proto-\u0444\u0430\u0439\u043b\u044b \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043f\u043e \u043f\u0430\u043f\u043a\u0430\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0Protos\/Models\/\u00a0\u0438\u00a0Protos\/Services\/\u00a0), \u0443 \u0432\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 .csproj:&lt;ItemGroup&gt;    &lt;!&#8212; \u041c\u043e\u0434\u0435\u043b\u0438: \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0438 \u043a Server, \u043d\u0438 \u043a Client &#8212;&gt;  &lt;Protobuf Include=&#187;Protos\\Models\\**\\*.proto&#187;&gt;    &lt;GrpcServices&gt;None&lt;\/GrpcServices&gt;    &lt;Access&gt;Public&lt;\/Access&gt;    &lt;ProtoCompile&gt;True&lt;\/ProtoCompile&gt;    &lt;ProtoRoot&gt;Protos&lt;\/ProtoRoot&gt; &lt;!&#8212; \u041a\u043e\u0440\u0435\u043d\u044c \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0430\u0448\u0438 import &#8212;&gt;  &lt;\/Protobuf&gt;    &lt;!&#8212; \u0421\u0435\u0440\u0432\u0438\u0441\u044b &#8212;&gt;  &lt;Protobuf Include=&#187;Protos\\Services\\**\\*.proto&#187;&gt;    &lt;GrpcServices&gt;Server&lt;\/GrpcServices&gt; &lt;!&#8212; Both &#8212; \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 &#8212;&gt;    &lt;Access&gt;Public&lt;\/Access&gt;    &lt;ProtoCompile&gt;True&lt;\/ProtoCompile&gt;    &lt;ProtoRoot&gt;Protos&lt;\/ProtoRoot&gt;    &lt;CompileOutputs&gt;True&lt;\/CompileOutputs&gt;  &lt;\/Protobuf&gt;  &lt;\/ItemGroup&gt;\u0421\u0430\u043c\u0430\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e Grpc.Tools \u0437\u0434\u0435\u0441\u044cNullable \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432\u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 int32 SomeDataOptional, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e \u043a\u0430\u043a optional, \u0442\u043e \u0432\u00a0\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043d\u0435\u00a0\u0431\u0443\u0434\u0435\u0442 int? SomeDataOptional { get; set; }. \u0411\u0443\u0434\u0435\u0442 int SomeDataOptional { get; set; }, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e HasSomeData, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0431\u044b\u043b\u043e \u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u043b\u0438\u00a0\u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a\u00a0\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e\u00a0&#8212; \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u00a0\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e &#8212; \u044d\u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0439 \u0442\u0438\u043f. \u041a\u043e\u0441\u0442\u044b\u043b\u044c, \u0447\u0442\u043e\u00a0\u0441\u043a\u0430\u0437\u0430\u0442\u044c.\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u00a0&#8212; google\/protobuf\/wrappers.proto. \u041f\u0440\u0438\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u0431\u0435\u0440\u0442\u043e\u043a (wrappers) \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e\u00a0\u043d\u0443\u0436\u043d\u043e: nullable\u2011\u0442\u0438\u043f \u0432\u00a0\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435.\u0415\u0441\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043e\u0431\u0435\u0440\u0442\u043a\u0438\u00a0&#8212; \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u0435\u0439, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0439 \u0442\u0438\u043f. \u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435\u00a0\u0442\u043e, \u0447\u0442\u043e\u00a0\u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0438\u0436\u0435.Nullable \u0434\u043b\u044f \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432\u0414\u043b\u044f \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445\u00a0message\u00a0) \u0138\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0439 \u043c\u0435\u0436\u0434\u0443\u00a0optional\u00a0\u0438 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e &#8212; \u043e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0434\u0430\u0434\u0443\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0431\u0435\u0437\u00a0?.\u041d\u0430\u0439\u0434\u0438 10 \u043e\u0442\u043b\u0438\u0447\u0438\u0439\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c optional \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c null. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445.Nullable \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 (enum)\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u043c \u0442\u0438\u043f\u0430\u043c:\u00a0optional enum\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e HasXXX \u0438 \u043c\u0435\u0442\u043e\u0434\u00a0ClearXXX\u00a0, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435\u00a0Nullable&lt;EnumType&gt;.\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u041f\u043e\u0434\u0445\u043e\u0434\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442optional EnumType fieldEnumType\u00a0+\u00a0HasXxx\u00a0\/\u00a0ClearXxx\u041e\u0431\u0451\u0440\u0442\u0138\u0430 message EnumWrapper {    EnumType value = 1; }\u00a0\u0414\u0430, \u044d\u0442\u043e \u043a\u0430\u043a \u0441 \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, \u043d\u043e \u0438\u043d\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b. \u0422\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c optional \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0430\u043a\u043e\u0433\u043e wrapper, \u0441\u043b\u0435\u0434\u0443\u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0435 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435. Decimal\u0412 protobuf \u043d\u0435\u0442 \u0442\u0438\u043f\u0430\u00a0decimal. \u041f\u0440\u044f\u043c\u044b\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b &#8212;\u00a0double\u00a0\u0438\u00a0float\u00a0, \u043d\u043e \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0434\u043b\u044f \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043f\u043e\u0442\u0435\u0440\u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438.\u0420\u0435\u0448\u0435\u043d\u0438\u0435google\/protobuf\/money.proto &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0443\u043c\u043c\u0443 \u0438 \u0432\u0430\u043b\u044e\u0442\u0443 (\u0441\u0442\u0440\u043e\u0138\u0430).DecimalValue\u00a0\u043f\u043e \u0440\u0435\u0446\u0435\u043f\u0442\u0443\u00a0Microsoft\u0412\u0430\u0436\u043d\u043e: \u0438\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435\u00a0implicit operator\u00a0\u0434\u043b\u044f \u0138\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438, \u0442\u0430\u0138 \u0138\u0430\u0138 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0138 NullReferenceException\u00a0\u043f\u0440\u0438\u00a0DecimalValue == null. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044f\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:public static class DecimalValueExtension{    private const decimal NanoFactor = 1_000_000_000;      public static decimal ToDecimal(this DecimalValue value)      =&gt; value.Units + value.Nanos \/ NanoFactor;      public static decimal? ToNullableDecimal(this DecimalValue? value)      =&gt; value is null ? null : value.ToDecimal();      public static DecimalValue ToDecimalValue(this decimal value)    {        var units = decimal.ToInt64(value);        var nanos = decimal.ToInt32((value &#8212; units) * NanoFactor);        return new DecimalValue { Units = units, Nanos = nanos };    }      public static DecimalValue? ToNullableDecimalValue(this decimal? value)      =&gt; value is null ? null : value.Value.ToDecimalValue();}DateTime \u0438 DateTimeOffset\u0412 protobuf \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u0442\u043e\u0439\/\u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c.\u0420\u0435\u0448\u0435\u043d\u0438\u0435\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u044d\u0442\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f google\/protobuf\/timestamp.proto, \u0434\u043b\u044f C# \u0443 \u043d\u0435\u0433\u043e \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:\u0414\u043b\u044f Timestamp: ToDateTime() \u0438 ToDateTimeOffset()\u0412 Timestamp:\u0418\u0437 DateTime: \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c DateTime \u0432 Timestamp \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u043a UTC, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u043c ToUniversalTime(), \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 ToTimestamp()\u0418\u0437 DateTimeOffset: \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 .ToTimestamp() \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439.\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u0138\u0442\u043d\u044b\u0435 \u0138\u043b\u0430\u0441\u0441\u044b\u0412 protobuf \u043d\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f (\u0438 oneof, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435). \u041c\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435, \u043e\u0431\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0430 \u0432\u044b \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u043b\u0438? \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c, \u0438 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c, \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c &#8212; \u0434\u0430 \u0435\u0441\u0442\u044c \u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u043c\u0438\u043d\u0443\u0441\u044b.\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f C#-\u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430[abstract] class Base{    public int Id { get; set; }}class User : Base{    public string Name { get; set; }}class UserAdditionalInfo : User{    public DateTimeOffset BDay { get; set; }}class Role : Base{    public int Priority { get; set; }    public string RoleName { get; set; }}class UseBaseClass{    public Base Base { get; set; }}\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)syntax = &#171;proto3&#187;;message Base {    int32 id = 1;}message User {    Base base = 1;    string name = 2;}message UserAdditionalInfo {    User base = 1;    google.protobuf.Timestamp b_day = 2;}message Role {    Base base = 1;    int32 priority = 2;    string role_name = 3;}\/\/ \u041d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\/\u043a\u043b\u0430\u0441\u0441, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0442\u0438\u043f\u043e\u043cmessage BaseChildrens {    oneof type {        User user = 1;        UserAdditionalInfo user_additional_info = 2;        Role role = 3;    }}message UseBaseClass {    BaseChildrens base = 1;}\u041c\u0435\u0442\u043e\u0434 \u043e\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c &#8212; \u0435\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0438\u043b\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 message, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434-\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434-\u043f\u043e\u0434-&#8230;\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0445 \u0138 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043csyntax = &#171;proto3&#187;;\/\/ \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439\/\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043emessage Base {    int32 id = 1;    oneof child {        User user = 2;        Role role = 3;    }}message User {  string name = 1;    oneof child {        UserAdditionalInfo user_additional_info = 2;    }}message UserAdditionalInfo {    google.protobuf.Timestamp b_day = 1;}message Role {    int32 priority = 1;    string role_name = 2;}message UseBaseClass {    Base base = 1; \/\/ \u0432\u0441\u0435 \u0442\u0430\u043a \u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439}\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21161: \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u2192 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0435\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u21162: \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u0138\u0438\u0435 \u2192 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435\u0427\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438\u2705 \u041b\u0443\u0447\u0448\u0435\u274c \u0425\u0443\u0436\u0435\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0138\u043b\u0430\u0441\u0441\u043e\u043c\u26a0\ufe0f \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f BaseChildrens, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c\u2705 \u0423\u0434\u043e\u0431\u043d\u043e, \u0443\u0436\u0435 \u0432\u0441\u0435 \u0435\u0441\u0442\u044cGeneric, aka \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b\u0417\u0430\u043f\u0438\u0441\u043a\u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 generic\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0434\u043d\u0435\u0432\u043d\u0438\u043a, \u043c\u043d\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u043b\u043e\u0432 \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u043b\u044c \u0438 \u0443\u043d\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0438\u0441\u043f\u044b\u0442\u0430\u043b \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043c\u043e\u044f \u0436\u0438\u0437\u043d\u044c \u043f\u043e\u043b\u043e\u043c\u0430\u043d\u0430 \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430&#8230;\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u043c\u0435\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 BaseEntity, \u0432 \u043a\u043e\u0434\u0435&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-479335","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/479335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=479335"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/479335\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=479335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=479335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=479335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}