Using a PrivateObject, I’m trying to create an instance of the ItemChange class (found here). Looking through the debugger as well as the object browser in Visual Studio 2008 I can’t seem to find anything related to the ItemId property other than a setter. Below is the code I am using.
var itemChange = new PrivateObject(typeof(ItemChange));
itemChange.SetFieldOrProperty("ChangeType", _fixture.CreateAnonymous<ChangeType>());
itemChange.SetFieldOrProperty("ItemId", _fixture.CreateAnonymous<ItemId>());
The error I receive is:
System.MissingMethodException : Method 'Microsoft.Exchange.WebServices.Data.ItemChange.ItemId' not found.
I’ve tried variations of BindingFlags, however nothing seems to help. How can I set a property that has no setter and only a getter?
Edit
Regarding my comments, the other inline class that I can create a PrivateObject object instance and set the ItemId is the ItemEvent class (found here). This class was easy because when I was debugging and added the class to my watch list I could see itemId as a private variable. However, performing the same steps on the ItemChange class I cannot find any traces of an ItemId field other than the property itself that only has a setter. This is where I’m stumped on how to set this property.
Lastly, I don’t have access to a tool that would allow me to decompile the class and see what is what.
If the property you are trying to set is read-only and not backed by any underlying private field, then you can’t actually set it. For example, if you had the following property:
nothing you do is ever going to set this property to another value. If you don’t see an obvious backing field when you look through the object’s fields in the debugger and/or reflection, this is likely the situation.
In this case, if I had to make a guess, I would say that ItemId is probably a shortcut property that simply returns
this.Item.Id.EDIT:
I was partly true. According to dotPeek,
ItemChange.ItemIdjust returnsChange.id, appropriately typecast. IfChange.serviceObjecthas a value, thanChange.idreturnsChange.serviceObject.GetId(), otherwise it returnsChange.id. Which of those is appropriate in your case depends on the kind of change you’re talking about, per MSDN:Effectively, the implementation of Change and ItemChange does something like this:
In the actual
Changeimplementation, the object field is aServiceObjectnamedserviceObject, which has aGetId()method that returns aServiceId, and there is also anidfield of typeServiceId. To get yourItemChangeobject’sItemIdproperty set, you need to set one or the other of those internal fields on the object’s base class (theserviceObjectfield takes precedence if it’s set.)