6

これが私のクラスの簡略版です。

public abstract class Task
{
    private static object LockObject = new object();

    protected virtual void UpdateSharedData() { }
    protected virtual void UpdateNonSharedData() { }

    public void Method()
    {
       lock(LockObject)
       {
          UpdateSharedData();
       }
       UpdateNonSharedData();
    }
}

派生クラスからロック コードを隠そうとしています。しかし、派生クラスが UpdateSharedData をオーバーライドする場合にのみ、ロックを取得したいと考えています。そうでない場合は、非共有データを更新する前に、共有データを更新する他のすべての実行中のインスタンスをメソッドがブロックして待機することは望ましくありません。

したがって、Method が行う (一見) 明白なことは、現在のインスタンスの UpdateSharedData の実装が基本クラスの実装をオーバーライドしているかどうかを確認することです。リフレクションを使用しないとこれは不可能であると確信しており、それを行うことはおそらく望ましくありません。

私はこれに対するいくつかの回避策を考えましたが、それらはすべてかなり厄介です:

  • 派生クラスのコンストラクターが設定する保護された bool プロパティを追加し、そのプロパティをチェックしてロックが必要かどうかを確認します。これは、派生クラスからロック コードを隠すという非常にひどい作業を行っています。
  • UpdateSharedData メソッドをデリゲート プロパティにし、派生クラスのコンストラクターでプロパティをプライベート メソッドに設定し、デリゲートが null でない場合にのみロックを取得します。それは良くなりましたが、それでもちょっとひどいです。
4

3 に答える 3

5

このチェックは、わずかなリフレクションで実行できます。

bool IsUpdateSharedDataOverridden()
{
    Type t = this.GetType();
    MethodInfo m = subType.GetMethod("UpdateSharedData");

    return m.DeclaringType == t && m.GetBaseDefinition().DeclaringType == typeof(Task);
}
于 2009-02-06T03:55:50.117 に答える
5

抽象 Task と IHasSharedData インターフェイスを定義した場合、ロックを実行する前に派生 Task が IHasSharedData を実装しているかどうかを Method で確認します。インターフェイスを実装するクラスだけが待機する必要があります。これにより実際の質問への回答が回避されることは理解していますが、リフレクションを使用するよりもクリーンなソリューションになると思います。うまくいけば、クラスが実際に行うことにより厳密に一致するインターフェイスのより良い名前が見つかるでしょう。

public interface IHasSharedData
{
    void UpdateSharedData();
}

public abstract class Task
{
    private static object LockObject = new object();

    protected virtual void UpdateNonSharedData() { }

    public void Method()
    {
         if (this is IHasSharedData)
         {
            lock(LockObject)
            {
                UpdateSharedData();
            }
         }
         UpdateNonSharedData();
    }
}

public class SharedDataTask : Task, IHasSharedData
{
    public void UpdateSharedData()
    {
       ...
    }
}
于 2009-02-06T03:59:49.267 に答える