Allon Guralnek
Allon Guralnek

Reputation: 16121

Other properties accessors besides 'set' and 'get'?

I was reflecting over properties of a type and wanted to check if a property has both a public setter and getter. Unfortunatly, PropertyInfo's CanRead and CanWrite doesn't indicate the accessibility level. So I turned to PropertyInfo.GetAccessors() which has an interesting description (emphasis mine):

Returns an array whose elements reflect the public get, set, and other accessors of the property reflected by the current instance.

What 'other accessors' are there? Is there merely a possibility for other accessors, or does a CLI language exists that actually has more than the simple set/get duo for a property?

Upvotes: 3

Views: 135

Answers (2)

phipsgabler
phipsgabler

Reputation: 20950

Events have add and remove accessors for registering delegates (that's what the += gets translated to).

EDIT: Ok, they have little to do with properties, but they fall under the category of "other accessors". EventInfo, interestingly, has only methods like GetAddMethod and GetRemoveMethod. Additionally, there's GetOtherMethod and GetRaiseMethod, but that's more dark magic I don't know much about...

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062660

In real terms, there is just a getter and setter. Technically, IIRC the CLI spec (ECMA 335 section 1.8.11.3) doesn't restrict to just these, so some other language would be free to add other meanings, but in reality none do.

This is shown in table II.17, and uses the .other caption in IL (note it is .get for the getter, .set for the setter and .custom for attributes).

edit

In particular, note the example included in the specification:

  // the declaration of the property 
  .property int32 Count() { 
    .get instance int32 MyCount::get_Count() 
    .set instance void MyCount::set_Count(int32) 
    .other instance void MyCount::reset_Count() 
  } 

This suggests that "reset" is an option; however, in reality this is handled via a reflection pattern; so for:

public int Foo {get;set;}

it is convention that public void ResetFoo() is the reset method for Foo, but the compiler does not process this into a custom accessor.

using System;
using System.ComponentModel;
public class MyType
{
    public int Foo { get; set; }
    public void ResetFoo() { Foo = 0; }

    static void Main()
    {
        var obj = new MyType {Foo = 123};
        TypeDescriptor.GetProperties(typeof(MyType))["Foo"].ResetValue(obj);
        Console.WriteLine(obj.Foo); // outputs: 0

        var accessors = typeof (MyType).GetProperty("Foo").GetAccessors();
        // writes get_Foo and set_Foo
        foreach(var acc in accessors) Console.WriteLine(acc.Name);
    }
}

Upvotes: 5

Related Questions