XINCGer/Unity3DTraining · error · ArgumentException

Cannot read from property

Error message

Cannot read from property

What it means

OneofAccessor's constructor requires the CLR case-discriminator property (e.g. 'MyOneofCase') to be readable, since it binds a getter delegate used to determine which oneof field is set. If PropertyInfo.CanRead is false it throws ArgumentException. This indicates a mismatch between the generated message type and the descriptor wiring.

Solutions

  1. Use the standard generated message classes so the Case property has a public getter.
  2. Pass the property obtained via ClrType.GetProperty(name + "Case") on the generated type rather than an unrelated property.
  3. Regenerate the C# code with protoc so case properties match the descriptor.

Example fix

// before
var prop = typeof(Msg).GetProperty("Choice", BindingFlags.NonPublic | BindingFlags.SetProperty);
new OneofAccessor(prop, clearMethod, oneofDesc); // throws
// after
var prop = typeof(Msg).GetProperty("ChoiceCase"); // readable generated case property
new OneofAccessor(prop, clearMethod, oneofDesc);
Defensive patterns

Strategy: validation

Validate before calling

var prop = typeof(Msg).GetProperty(oneofName + "Case");
if (prop == null || !prop.CanRead) throw new InvalidOperationException($"Readable '{oneofName}Case' property required");

Type guard

bool IsReadableOneofCase(PropertyInfo p) => p != null && p.CanRead;

Try / catch

try { accessor = new OneofAccessor(prop, clearMethod, desc); } catch (ArgumentException ex) { log.Error($"Bad oneof property: {ex.Message}"); throw; }

Prevention

When it happens

Trigger: Constructing a OneofAccessor directly (or via OneofDescriptor.CreateAccessor) with a PropertyInfo for the oneof case property that is write-only or otherwise unreadable.

Common situations: Custom reflection tooling building accessors over generated protobuf classes, or generated code whose case property was replaced/hidden by partial-class shadowing.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12). Data as JSON: /api/errors/beab3c20a9c0e035. Report an issue: GitHub.

Appendix: source

Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/OneofAccessor.cs:52

using System.Reflection;
// using Google.Protobuf.Compatibility;

namespace Google.Protobuf.Reflection
{
    /// <summary>
    /// Reflection access for a oneof, allowing clear and "get case" actions.
    /// </summary>
    public sealed class OneofAccessor
    {
        private readonly Func<IMessage, int> caseDelegate;
        private readonly Action<IMessage> clearDelegate;
        private OneofDescriptor descriptor;

        internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor)
        {
            if (!caseProperty.CanRead)
            {
                throw new ArgumentException("Cannot read from property");
            }
            this.descriptor = descriptor;
            caseDelegate = ReflectionUtil.CreateFuncIMessageT<int>(caseProperty.GetGetMethod());

            this.descriptor = descriptor;
            clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod);
        }

        /// <summary>
        /// Gets the descriptor for this oneof.
        /// </summary>
        /// <value>
        /// The descriptor of the oneof.
        /// </value>
        public OneofDescriptor Descriptor { get { return descriptor; } }

        /// <summary>
        /// Clears the oneof in the specified message.

View on GitHub (pinned to 016f98412e)