While a FieldDescriptor describes the field, it does not provide
any way of obtaining or changing the value of the field within a specific message;
that is the responsibility of the accessor.
In descriptors for generated code, 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, and the value of the map field itself is represented by a dictionary in the
reflection API. There are never instances of those "hidden" messages, so no accessor is provided
and this property will return null.
In dynamically loaded descriptors, the value returned by this property will current be null;
if and when dynamic messages are supported, it will return a suitable accessor to work with
them.
ContainingOneof
public OneofDescriptor ContainingOneof { get; }
Returns the oneof containing this field, or null if it is not part of a oneof.
Indicates whether this field supports presence, either implicitly (e.g. due to it being a message
type field) or explicitly via Has/Clear members. If this returns true, it is safe to call
Clear(IMessage) and HasValue(IMessage)
on this field's accessor with a suitable message.
The effective JSON name for this field. This is usually the lower-camel-cased form of the field name,
but can be overridden using the json_name option in the .proto file.
Compares this descriptor with another one, ordering in "canonical" order
which simply means ascending order by field number. other
must be a field of the same type, i.e. the ContainingType of
both fields must be the same.
The FieldOptions, 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 FieldDescriptorProto describing this field.
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\u003eFieldDescriptor\u003c/code\u003e class provides a description of a field or extension within a message defined in a .proto file.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003eFieldDescriptor\u003c/code\u003e implements \u003ccode\u003eIDescriptor\u003c/code\u003e and \u003ccode\u003eIComparable<FieldDescriptor>\u003c/code\u003e, allowing it to be used for field comparisons and within descriptor-based operations.\u003c/p\u003e\n"],["\u003cp\u003eIt exposes properties to access field details such as \u003ccode\u003eFieldType\u003c/code\u003e, \u003ccode\u003eFieldNumber\u003c/code\u003e, \u003ccode\u003eJsonName\u003c/code\u003e, whether it's an extension, and various type-related information.\u003c/p\u003e\n"],["\u003cp\u003eIt provides methods to retrieve field options, including \u003ccode\u003eGetOptions()\u003c/code\u003e, which retrieves \u003ccode\u003eFieldOptions\u003c/code\u003e, and \u003ccode\u003eToProto()\u003c/code\u003e, which returns a \u003ccode\u003eFieldDescriptorProto\u003c/code\u003e representation.\u003c/p\u003e\n"],["\u003cp\u003eAccessor and OneOf information is provided by \u003ccode\u003eAccessor\u003c/code\u003e and \u003ccode\u003eContainingOneof\u003c/code\u003e, respectively, to retrieve their associated objects, with the former returning null if no accessor is provided.\u003c/p\u003e\n"]]],[],null,["# Class FieldDescriptor (3.27.1)\n\nVersion latestkeyboard_arrow_down\n\n- [3.27.1 (latest)](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.FieldDescriptor)\n- [3.23.0](/dotnet/docs/reference/Google.Protobuf/3.23.0/Google.Protobuf.Reflection.FieldDescriptor)\n- [3.15.8](/dotnet/docs/reference/Google.Protobuf/3.15.8/Google.Protobuf.Reflection.FieldDescriptor) \n\n public sealed class FieldDescriptor : DescriptorBase, IDescriptor, IComparable\u003cFieldDescriptor\u003e\n\nDescriptor for a field or extension within a message in a .proto file. \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 FieldDescriptor \n\nImplements\n----------\n\n[IDescriptor](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.IDescriptor), [IComparable](https://learn.microsoft.com/dotnet/api/system.icomparable-1)[FieldDescriptor](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.FieldDescriptor) \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### Accessor\n\n public IFieldAccessor Accessor { get; }\n\nReturns the accessor for this field.\n\n**Remarks** \n\nWhile a [FieldDescriptor](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.FieldDescriptor) describes the field, it does not provide\nany way of obtaining or changing the value of the field within a specific message;\nthat is the responsibility of the accessor.\n\n\nIn descriptors for generated code, the value returned by this property will be non-null for all\nregular fields. However, if 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, and the value of the map field itself is represented by a dictionary in the\nreflection API. There are never instances of those \"hidden\" messages, so no accessor is provided\nand this property will return null.\n\n\nIn dynamically loaded descriptors, the value returned by this property will current be null;\nif and when dynamic messages are supported, it will return a suitable accessor to work with\nthem.\n\n### ContainingOneof\n\n public OneofDescriptor ContainingOneof { get; }\n\nReturns the oneof containing this field, or `null` if it is not part of a oneof.\n\n### ContainingType\n\n public MessageDescriptor ContainingType { get; }\n\nGet the field's containing message type, or `null` if it is a field defined at the top level of a file as an extension.\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 field.\n\n### EnumType\n\n public EnumDescriptor EnumType { get; }\n\nFor enum fields, returns the field's type.\n\n### ExtendeeType\n\n public MessageDescriptor ExtendeeType { get; }\n\nFor extension fields, returns the extended type\n\n### Extension\n\n public Extension Extension { get; }\n\nAn extension identifier for this field, or `null` if this field isn't an extension.\n\n### FieldNumber\n\n public int FieldNumber { get; }\n\nReturns the field number declared in the proto file.\n\n### FieldType\n\n public FieldType FieldType { get; }\n\nReturns the type of the field.\n\n### HasPresence\n\n public bool HasPresence { get; }\n\nIndicates whether this field supports presence, either implicitly (e.g. due to it being a message\ntype field) or explicitly via Has/Clear members. If this returns true, it is safe to call\n[Clear(IMessage)](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.IFieldAccessor#Google_Protobuf_Reflection_IFieldAccessor_Clear_Google_Protobuf_IMessage_) and [HasValue(IMessage)](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.IFieldAccessor#Google_Protobuf_Reflection_IFieldAccessor_HasValue_Google_Protobuf_IMessage_)\non this field's accessor with a suitable message.\n\n### IsExtension\n\n public bool IsExtension { get; }\n\nReturns `true` if this field extends another message type; `false` otherwise.\n\n### IsMap\n\n public bool IsMap { get; }\n\nReturns `true` if this field is a map field; `false` otherwise.\n\n### IsPacked\n\n public bool IsPacked { get; }\n\nReturns `true` if this field is a packed, repeated field; `false` otherwise.\n\n### IsRepeated\n\n public bool IsRepeated { get; }\n\nReturns `true` if this field is a repeated field; `false` otherwise.\n\n### IsRequired\n\n public bool IsRequired { get; }\n\nReturns `true` if this field is a required field; `false` otherwise.\n\n### JsonName\n\n public string JsonName { get; }\n\nThe effective JSON name for this field. This is usually the lower-camel-cased form of the field name,\nbut can be overridden using the `json_name` option in the .proto file.\n\n### MessageType\n\n public MessageDescriptor MessageType { get; }\n\nFor embedded message and group fields, returns the field's type.\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### PropertyName\n\n public string PropertyName { get; }\n\nThe name of the property in the `ContainingType.ClrType` class.\n\n### RealContainingOneof\n\n public OneofDescriptor RealContainingOneof { get; }\n\nReturns the oneof containing this field if it's a \"real\" oneof, or `null` if either this\nfield is not part of a oneof, or the oneof is synthetic.\n\nMethods\n-------\n\n### CompareTo(FieldDescriptor)\n\n public int CompareTo(FieldDescriptor other)\n\nCompares this descriptor with another one, ordering in \"canonical\" order\nwhich simply means ascending order by field number. `other`\nmust be a field of the same type, i.e. the [ContainingType](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.FieldDescriptor#Google_Protobuf_Reflection_FieldDescriptor_ContainingType) of\nboth fields must be the same.\n\n### GetOption\\\u003cT\\\u003e(Extension\\\u003cFieldOptions, T\\\u003e)\n\n [Obsolete(\"GetOption is obsolete. Use the GetOptions() method.\")]\n public T GetOption\u003cT\u003e(Extension\u003cFieldOptions, T\u003e extension)\n\nGets a single value field option for this descriptor\n\n### GetOption\\\u003cT\\\u003e(RepeatedExtension\\\u003cFieldOptions, T\\\u003e)\n\n [Obsolete(\"GetOption is obsolete. Use the GetOptions() method.\")]\n public RepeatedField\u003cT\u003e GetOption\u003cT\u003e(RepeatedExtension\u003cFieldOptions, T\u003e extension)\n\nGets a repeated value field option for this descriptor\n\n### GetOptions()\n\n public FieldOptions GetOptions()\n\nThe `FieldOptions`, 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 FieldDescriptorProto ToProto()\n\nReturns a clone of the underlying [FieldDescriptorProto](/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.Reflection.FieldDescriptorProto) describing this field.\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."]]