Given a PropertyInfo object, how can I check that the setter of the property is public?
.NET properties are really a wrapping shell around a get and set method.
You can use the GetSetMethod
method on the PropertyInfo, returning the MethodInfo referring to the setter. You can do the same thing with GetGetMethod
.
These methods will return null if the getter/setter is non-public.
The correct code here is:
bool IsPublic = propertyInfo.GetSetMethod() != null;
Check what you get back from GetSetMethod
:
MethodInfo setMethod = propInfo.GetSetMethod();
if (setMethod == null)
{
// The setter doesn't exist or isn't public.
}
Or, to put a different spin on Richard's answer:
if (propInfo.CanWrite && propInfo.GetSetMethod(/*nonPublic*/ true).IsPublic)
{
// The setter exists and is public.
}
Note that if all you want to do is set a property as long as it has a setter, you don't actually have to care whether the setter is public. You can just use it, public or private:
// This will give you the setter, whatever its accessibility,
// assuming it exists.
MethodInfo setter = propInfo.GetSetMethod(/*nonPublic*/ true);
if (setter != null)
{
// Just be aware that you're kind of being sneaky here.
setter.Invoke(target, new object[] { value });
}
public class Program
{
class Foo
{
public string Bar { get; private set; }
}
static void Main(string[] args)
{
var prop = typeof(Foo).GetProperty("Bar");
if (prop != null)
{
// The property exists
var setter = prop.GetSetMethod(true);
if (setter != null)
{
// There's a setter
Console.WriteLine(setter.IsPublic);
}
}
}
}
You need to use the underling method to determine accessibility, using PropertyInfo.GetGetMethod() or PropertyInfo.GetSetMethod().
// Get a PropertyInfo instance...
var info = typeof(string).GetProperty ("Length");
// Then use the get method or the set method to determine accessibility
var isPublic = (info.GetGetMethod(true) ?? info.GetSetMethod(true)).IsPublic;
Note, however, that the getter & setter may have different accessibilities, e.g.:
class Demo {
public string Foo {/* public/* get; protected set; }
}
So you can't assume that the getter and the setter will have the same visibility.