1

を使用して、クラスPrivateObjectのインスタンスを作成しようとしています(ここにあります)。デバッガーと Visual Studio 2008 のオブジェクト ブラウザーを調べたところ、setter 以外のプロパティに関連するものは見つかりませんでした。以下は私が使用しているコードです。ItemChangeItemId

var itemChange = new PrivateObject(typeof(ItemChange));

itemChange.SetFieldOrProperty("ChangeType", _fixture.CreateAnonymous<ChangeType>());
itemChange.SetFieldOrProperty("ItemId", _fixture.CreateAnonymous<ItemId>());

私が受け取るエラーは次のとおりです。

System.MissingMethodException : Method 'Microsoft.Exchange.WebServices.Data.ItemChange.ItemId' not found.

のバリエーションを試しましたがBindingFlags、何も役に立たないようです。セッターがなく、ゲッターのみのプロパティを設定するにはどうすればよいですか?

編集

私のコメントに関しては、PrivateObjectオブジェクト インスタンスを作成して設定できる他のインライン クラスItemIdItemEventクラスです (ここにあります)。このクラスは簡単でした。なぜなら、デバッグ中にこのクラスをウォッチ リストに追加したときにitemId、プライベート変数として表示されたからです。ただし、ItemChangeクラスで同じ手順を実行しても、セッターしかないプロパティ自体以外のフィールドの痕跡は見つかりませんこれは、このプロパティを設定する方法に困惑しているところです。ItemId

最後に、クラスを逆コンパイルして何が何であるかを確認できるツールにアクセスできません。

4

2 に答える 2

2

パブリックget-onlyプロパティには、必ずしもプライベートセッターがあるとは限りません。ターゲットクラスを自分で作成していない場合は、プロパティゲッターによって返される値を変更するために、Reflectorなどの逆コンパイラーを取得して何を変更する必要があるかを把握する必要があります。

この種のことを頻繁に行う必要がある場合は、適切な拡張フックなしでサードパーティのコードの動作を制御するための代替アプローチの使用を検討することをお勧めします。たとえば、Molesを使用すると、プロパティやクラスの内部について何も知らなくても、ゲッターの代わりに自分の希望する動作を使用できます。

于 2012-04-13T14:47:58.377 に答える
1

設定しようとしているプロパティが読み取り専用であり、基になるプライベート フィールドによってサポートされていない場合、実際に設定することはできません。たとえば、次のプロパティがあるとします。

public string ItemId
{
  get 
  {
    return "Test";
  }
}

このプロパティを別の値に設定することはありません。デバッガーおよび/またはリフレクションでオブジェクトのフィールドを調べたときに、明らかなバッキング フィールドが表示されない場合、これが状況である可能性があります。

この場合、推測する必要があるとすれば、ItemId はおそらく単に を返すショートカット プロパティであると言えますthis.Item.Id

編集:

私は部分的に真実でした。dotPeek によると、適切に型キャストされた をItemChange.ItemId返すだけです。Change.idChange.serviceObjectがある場合は をChange.id返しChange.serviceObject.GetId()、そうでない場合は を返しますChange.id。あなたの場合にどちらが適切かは、MSDN によると、話している変更の種類によって異なります。

ChangeType プロパティの値が ChangeType.Delete または ChangeType.ReadFlagChange の場合、Item は null です。

実際には、Change と ItemChange の実​​装は次のようになります。

public class Base 
{
  private Thing thing;
  private BaseId id;

  internal BaseId Id
  {
    get
    {
      return this.thing == null ? this.id : this.thing.GetId();
    }
  }
}

public class Child
{
  public ChildId ChildId
  {
    get 
    { 
      return (ChildId) this.Id; 
    }
  }
}

実際のChange実装では、 object フィールドはServiceObjectnamedserviceObjectであり、これにはGetId()を返すメソッドがあり、 typeServiceIdのフィールドもあります。オブジェクトのプロパティ セットを取得するには、オブジェクトの基本クラスでこれらの内部フィールドのいずれかを設定する必要があります (設定されている場合は、フィールドが優先されます)。idServiceIdItemChangeItemIdserviceObject

于 2012-04-13T14:49:10.573 に答える