The value returned by this property will be non-null for all regular fields. However,
if a message containing a map field is introspected, the list of nested messages will include
an auto-generated nested key/value pair message for the field. This is not represented in any
generated type, so this property will return null in such cases.
For wrapper types (StringValue and the like), the type returned here
will be the generated message type, not the native type used by reflection for fields of those types. Code
using reflection should call IsWrapperType to determine whether a message descriptor represents
a wrapper type, and handle the result appropriately.
An unmodifiable list of this message type's enum types.
Extensions
public ExtensionCollection Extensions { get; }
An unmodifiable list of extensions defined in this message's scope.
Note that some extensions may be incomplete (FieldDescriptor.Extension may be null)
if they are declared in a file generated using a version of protoc that did not fully
support extensions in C#.
An unmodifiable list of the "oneof" field collections in this message type.
All "real" oneofs (where IsSynthetic returns false)
come before synthetic ones.
As MessageDescriptor is not generic, this cannot be statically
typed to the relevant type, but it should produce objects of a type compatible with ClrType.
The value returned by this property will be non-null for all regular fields. However,
if a message containing a map field is introspected, the list of nested messages will include
an auto-generated nested key/value pair message for the field. No message parser object is created for
such messages, so this property will return null in such cases.
For wrapper types (StringValue and the like), the parser returned here
will be the generated message type, not the native type used by reflection for fields of those types. Code
using reflection should call IsWrapperType to determine whether a message descriptor represents
a wrapper type, and handle the result appropriately.
RealOneofCount
public int RealOneofCount { get; }
The number of real "oneof" descriptors in this message type. Every element in Oneofs
with an index less than this will have a IsSynthetic property value
of false; every element with an index greater than or equal to this will have a
IsSynthetic property value of true.
The MessageOptions, defined in descriptor.proto.
If the options message is not present (i.e. there are no options), null is returned.
Custom options can be retrieved as extensions of the returned message.
NOTE: A defensive copy is created each time this property is retrieved.
Returns a clone of the underlying DescriptorProto describing this message.
Note that a copy is taken every time this method is called, so clients using it frequently
(and not modifying it) may want to cache the returned value.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-07 UTC."],[[["\u003cp\u003eThe \u003ccode\u003eMessageDescriptor\u003c/code\u003e class describes a message type and implements the \u003ccode\u003eIDescriptor\u003c/code\u003e interface within the \u003ccode\u003eGoogle.Protobuf.Reflection\u003c/code\u003e namespace.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003eMessageDescriptor\u003c/code\u003e provides properties such as \u003ccode\u003eClrType\u003c/code\u003e, \u003ccode\u003eContainingType\u003c/code\u003e, \u003ccode\u003eEnumTypes\u003c/code\u003e, \u003ccode\u003eExtensions\u003c/code\u003e, \u003ccode\u003eFields\u003c/code\u003e, \u003ccode\u003eName\u003c/code\u003e, \u003ccode\u003eNestedTypes\u003c/code\u003e, \u003ccode\u003eOneofs\u003c/code\u003e, and \u003ccode\u003eParser\u003c/code\u003e to access details about the message structure and functionality.\u003c/p\u003e\n"],["\u003cp\u003eIt includes methods like \u003ccode\u003eFindDescriptor\u003c/code\u003e, \u003ccode\u003eFindFieldByName\u003c/code\u003e, \u003ccode\u003eFindFieldByNumber\u003c/code\u003e, and \u003ccode\u003eGetOptions\u003c/code\u003e for locating and retrieving specific elements within the message's definition.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eMessageDescriptor\u003c/code\u003e class offers methods to access custom options and the underlying protobuf representation, including deprecated options using methods such as \u003ccode\u003eGetOption\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eThe versions included for this documentation are 3.27.1, 3.23.0, and 3.15.8, with the latest version being 3.27.1.\u003c/p\u003e\n"]]],[],null,["# Class MessageDescriptor (3.27.1)\n\nVersion latestkeyboard_arrow_down\n\n- [3.27.1 (latest)](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor)\n- [3.23.0](/dotnet/docs/reference/Google.Protobuf/3.23.0/Google.Protobuf.Reflection.MessageDescriptor)\n- [3.15.8](/dotnet/docs/reference/Google.Protobuf/3.15.8/Google.Protobuf.Reflection.MessageDescriptor) \n\n public sealed class MessageDescriptor : DescriptorBase, IDescriptor\n\nDescribes a message type. \n\nInheritance\n-----------\n\n[object](https://learn.microsoft.com/dotnet/api/system.object) \\\u003e [DescriptorBase](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase) \\\u003e MessageDescriptor \n\nImplements\n----------\n\n[IDescriptor](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.IDescriptor) \n\nInherited Members\n-----------------\n\n[DescriptorBase.Index](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase#Google_Protobuf_Reflection_DescriptorBase_Index) \n[DescriptorBase.FullName](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase#Google_Protobuf_Reflection_DescriptorBase_FullName) \n[DescriptorBase.File](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase#Google_Protobuf_Reflection_DescriptorBase_File) \n[DescriptorBase.Declaration](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase#Google_Protobuf_Reflection_DescriptorBase_Declaration) \n[object.Equals(object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)) \n[object.Equals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)) \n[object.GetHashCode()](https://learn.microsoft.com/dotnet/api/system.object.gethashcode) \n[object.GetType()](https://learn.microsoft.com/dotnet/api/system.object.gettype) \n[object.ReferenceEquals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.referenceequals) \n[object.ToString()](https://learn.microsoft.com/dotnet/api/system.object.tostring)\n\nNamespace\n---------\n\n[Google.Protobuf.Reflection](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection)\n\nAssembly\n--------\n\nGoogle.Protobuf.dll\n\nProperties\n----------\n\n### ClrType\n\n public Type ClrType { get; }\n\nThe CLR type used to represent message instances from this descriptor.\n\n**Remarks** \n\nThe value returned by this property will be non-null for all regular fields. However,\nif a message containing a map field is introspected, the list of nested messages will include\nan auto-generated nested key/value pair message for the field. This is not represented in any\ngenerated type, so this property will return null in such cases.\n\n\nFor wrapper types ([StringValue](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.WellKnownTypes.StringValue) and the like), the type returned here\nwill be the generated message type, not the native type used by reflection for fields of those types. Code\nusing reflection should call [IsWrapperType](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor#Google_Protobuf_Reflection_MessageDescriptor_IsWrapperType) to determine whether a message descriptor represents\na wrapper type, and handle the result appropriately.\n\n### ContainingType\n\n public MessageDescriptor ContainingType { get; }\n\n### CustomOptions\n\n [Obsolete(\"CustomOptions are obsolete. Use the GetOptions() method.\")]\n public CustomOptions CustomOptions { get; }\n\nThe (possibly empty) set of custom options for this message.\n\n### EnumTypes\n\n public IList\u003cEnumDescriptor\u003e EnumTypes { get; }\n\n### Extensions\n\n public ExtensionCollection Extensions { get; }\n\nAn unmodifiable list of extensions defined in this message's scope.\nNote that some extensions may be incomplete (FieldDescriptor.Extension may be null)\nif they are declared in a file generated using a version of protoc that did not fully\nsupport extensions in C#.\n\n### Fields\n\n public MessageDescriptor.FieldCollection Fields { get; }\n\n### Name\n\n public override string Name { get; }\n\nThe brief name of the descriptor's target.\n\n**Overrides** \n[DescriptorBase.Name](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorBase#Google_Protobuf_Reflection_DescriptorBase_Name)\n\n### NestedTypes\n\n public IList\u003cMessageDescriptor\u003e NestedTypes { get; }\n\n### Oneofs\n\n public IList\u003cOneofDescriptor\u003e Oneofs { get; }\n\n### Parser\n\n public MessageParser Parser { get; }\n\nA parser for this message type.\n\n**Remarks** \n\nAs [MessageDescriptor](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor) is not generic, this cannot be statically\ntyped to the relevant type, but it should produce objects of a type compatible with [ClrType](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor#Google_Protobuf_Reflection_MessageDescriptor_ClrType).\n\n\nThe value returned by this property will be non-null for all regular fields. However,\nif a message containing a map field is introspected, the list of nested messages will include\nan auto-generated nested key/value pair message for the field. No message parser object is created for\nsuch messages, so this property will return null in such cases.\n\n\nFor wrapper types ([StringValue](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.WellKnownTypes.StringValue) and the like), the parser returned here\nwill be the generated message type, not the native type used by reflection for fields of those types. Code\nusing reflection should call [IsWrapperType](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor#Google_Protobuf_Reflection_MessageDescriptor_IsWrapperType) to determine whether a message descriptor represents\na wrapper type, and handle the result appropriately.\n\n### RealOneofCount\n\n public int RealOneofCount { get; }\n\nThe number of real \"oneof\" descriptors in this message type. Every element in [Oneofs](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.MessageDescriptor#Google_Protobuf_Reflection_MessageDescriptor_Oneofs)\nwith an index less than this will have a [IsSynthetic](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.OneofDescriptor#Google_Protobuf_Reflection_OneofDescriptor_IsSynthetic) property value\nof `false`; every element with an index greater than or equal to this will have a\n[IsSynthetic](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.OneofDescriptor#Google_Protobuf_Reflection_OneofDescriptor_IsSynthetic) property value of `true`.\n\nMethods\n-------\n\n### FindDescriptor\\\u003cT\\\u003e(string)\n\n public T FindDescriptor\u003cT\u003e(string name) where T : class, IDescriptor\n\nFinds a nested descriptor by name. The is valid for fields, nested\nmessage types, oneofs and enums.\n\n### FindFieldByName(string)\n\n public FieldDescriptor FindFieldByName(string name)\n\nFinds a field by field name.\n\n### FindFieldByNumber(int)\n\n public FieldDescriptor FindFieldByNumber(int number)\n\nFinds a field by field number.\n\n### GetOption\\\u003cT\\\u003e(Extension\\\u003cMessageOptions, T\\\u003e)\n\n [Obsolete(\"GetOption is obsolete. Use the GetOptions() method.\")]\n public T GetOption\u003cT\u003e(Extension\u003cMessageOptions, T\u003e extension)\n\nGets a single value message option for this descriptor\n\n### GetOption\\\u003cT\\\u003e(RepeatedExtension\\\u003cMessageOptions, T\\\u003e)\n\n [Obsolete(\"GetOption is obsolete. Use the GetOptions() method.\")]\n public RepeatedField\u003cT\u003e GetOption\u003cT\u003e(RepeatedExtension\u003cMessageOptions, T\u003e extension)\n\nGets a repeated value message option for this descriptor\n\n### GetOptions()\n\n public MessageOptions GetOptions()\n\nThe `MessageOptions`, defined in `descriptor.proto`.\nIf the options message is not present (i.e. there are no options), `null` is returned.\nCustom options can be retrieved as extensions of the returned message.\nNOTE: A defensive copy is created each time this property is retrieved.\n\n### ToProto()\n\n public DescriptorProto ToProto()\n\nReturns a clone of the underlying [DescriptorProto](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.DescriptorProto) describing this message.\nNote that a copy is taken every time this method is called, so clients using it frequently\n(and not modifying it) may want to cache the returned value."]]