property setter
public access
C# programming
code validation
software development

How to check if property setter is public

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, checking whether a property setter is public is a reflection question, not a CanWrite question. CanWrite only tells you that some setter exists; it does not tell you whether that setter is public, private, protected, or internal.

Why CanWrite Is Not Enough

Consider this property:

csharp
public string Name { get; private set; }

Reflection will report that the property is writable in the sense that a setter exists. But that setter is not public.

So this:

csharp
property.CanWrite

is not the same as:

"Can outside callers invoke the setter?"

To answer that second question, inspect the setter method itself.

The Basic Reflection Pattern

Use PropertyInfo.GetSetMethod:

csharp
1using System;
2using System.Reflection;
3
4public class Person
5{
6    public string PublicValue { get; set; } = "";
7    public string PrivateValue { get; private set; } = "";
8}
9
10public class Program
11{
12    public static void Main()
13    {
14        Type type = typeof(Person);
15
16        foreach (PropertyInfo property in type.GetProperties())
17        {
18            MethodInfo? setter = property.GetSetMethod(nonPublic: true);
19            bool isPublicSetter = setter != null && setter.IsPublic;
20
21            Console.WriteLine($"{property.Name}: {isPublicSetter}");
22        }
23    }
24}

This asks reflection for the setter even if it is non-public, then inspects IsPublic.

Why GetSetMethod(true) Matters

If you call:

csharp
property.GetSetMethod()

without arguments, reflection returns only the public setter. That can be enough if all you care about is a boolean yes or no:

csharp
bool hasPublicSetter = property.GetSetMethod() != null;

But if you want to distinguish between:

  • no setter at all,
  • non-public setter,
  • and public setter,

then GetSetMethod(nonPublic: true) gives you the full picture.

A Reusable Helper

You can wrap this in a helper method:

csharp
1using System.Reflection;
2
3public static class ReflectionHelpers
4{
5    public static bool HasPublicSetter(PropertyInfo property)
6    {
7        MethodInfo? setter = property.GetSetMethod(nonPublic: true);
8        return setter != null && setter.IsPublic;
9    }
10}

Usage:

csharp
PropertyInfo property = typeof(Person).GetProperty(nameof(Person.PublicValue))!;
Console.WriteLine(ReflectionHelpers.HasPublicSetter(property));

This is often cleaner in validation frameworks or metadata-driven code.

Other Setter Access Levels

The same setter method also exposes other access flags:

  • 'IsPrivate'
  • 'IsFamily for protected'
  • 'IsAssembly for internal'

So if your real question is not just "public or not," you can inspect the exact access level:

csharp
1MethodInfo? setter = property.GetSetMethod(nonPublic: true);
2
3if (setter != null)
4{
5    Console.WriteLine(setter.IsPublic);
6    Console.WriteLine(setter.IsPrivate);
7    Console.WriteLine(setter.IsFamily);
8    Console.WriteLine(setter.IsAssembly);
9}

That is useful in serializers, mappers, and tooling that treat internal or protected setters specially.

Auto-Properties and Manual Properties Work the Same Way

Reflection does not care whether the property is an auto-property or a hand-written property with a backing field. The setter still compiles into a method, and that method still carries accessibility information.

So the same reflection logic applies to:

  • 'public string Name { get; set; }'
  • 'public string Name { get; private set; }'
  • or a property with a fully custom setter body.

When This Is Useful

Typical use cases include:

  • serializer configuration,
  • testing and code validation,
  • generic UI editors,
  • plugin systems,
  • and runtime mapping tools.

Whenever behavior depends on whether a caller can assign through a property, the setter method is the source of truth.

Common Pitfalls

The biggest pitfall is using CanWrite and assuming it means "publicly writable." It does not.

Another mistake is calling GetSetMethod() without nonPublic: true and then being unable to tell whether the setter is missing or merely non-public.

Developers also sometimes inspect property attributes or naming conventions instead of the actual reflected setter method. The method access flags are the authoritative answer.

Finally, remember that reflection answers runtime metadata questions. It does not override language accessibility rules for ordinary code.

Summary

  • 'PropertyInfo.CanWrite only means a setter exists somewhere.'
  • To check public accessibility, inspect the setter method.
  • 'property.GetSetMethod(nonPublic: true) plus setter.IsPublic is the reliable pattern.'
  • Use the same method flags to distinguish private, protected, and internal setters.
  • Reflection works the same way for auto-properties and custom property implementations.

Course illustration
Course illustration

All Rights Reserved.