「実行可能な」もののためのミニフレームワークに取り組んでいます。(実験、テスト、タスクなどです)
// Something that "runs" (in some coordinated way) multiple "runnable" things.
interface IRunnableOf<T> where : IRunnable
// Provide base-class functionality for a "runner"
abstract class RunnerBase<T> : IRunnableOf<T>
class SequentialRunner<T> : RunnerBase<T> // Same interface, different behavior.
class ConcurrentRunner<T> : RunnerBase<T>
// other types of runners.
class ConcurrentBlockRunner : SequentialRunner<Block>
class SequentialBlockRunner : ConcurrentRunner<Block>
さて、どうすれば と を調和させることができるConcurrentBlockRunner
でしょSequentialBlockRunner
うか? これにより、次のことを意味します。
コレクションで使用するために、共通の祖先によってそれらを参照します。(
IEnuerable<T>
ここで T = ??)追加の基本クラス機能を提供します。(たとえば、プロパティを追加します)。
型パラメーターを指定した別のインターフェイスを追加することで、#1 を修正しましたIA<T>
。
interface IBlockRunner : IRunnableOf<Block> { }
myConcurrentBlockRunner
と のSequentialBlockRunner
定義を次のように変更しました。
class ConcurrentBlockRunner : SequentialRunner<Block>, IBlockRunner
class SequentialBlockRunner : ConcurrentRunner<Block>, IBlockRunner
ConcurrentBlockRunner
とSequentialBlockRunner
の両方Block
が型パラメーターに使用されているため、これは正しい解決策のようです。しかし、私はそれについて「奇妙」に感じずにはいられません。まあ、そのインターフェイスを追加しただけだからです。
#2 では、 と にいくつかの共通データを追加しConcurrentBlockRunner
ますSequentialBlockRunner
。それらに適用されるいくつかのプロパティがありますが、RunnerBase<T>
.
C# を使用していて、多重継承が役立つと感じたのはこれが初めてです。私ができるなら:
abstract class BlockRunnerBase {
int Prop1 { get; set; }
int Prop2 { get; set; }
class ConcurrentBlockRunner : SequentialRunner<Block>, BlockRunnerBase
class SequentialBlockRunner : ConcurrentRunner<Block>, BlockRunnerBase
次に、これらの追加のプロパティを BlockRunnerBase に追加するだけで、すべてが機能します。より良い方法はありますか?
私は、私が作業を開始した構成をすぐに検討するように勧められることを知っています。
class BlockRunner : IBlockRunner {
IBlockRunner _member;
int Prop1 { get; set; } // Wish I could put these in some base class
int Prop2 { get; set; }
// Lots of proxy calls, and proxy events into _member
void Method() { _member.Method(); }
event SomeEvent
{
add { _member.SomeEvent += value; }
remove { _member.SomeEvent -= value; }
}
}
私が遭遇した問題(この質問を書くように私を駆り立てた)は、一度作成すると型の互換性が失われることでした。私の場合、 _member がイベントを発生させていたので、sender
パラメーターは typeSequentialBlockRunner
でした。ただし、イベント ハンドラーはそれを type にキャストしようとしましたがBlockRunner
、もちろん失敗しました。add
/remove
を使用してイベントをプロキシするのではなく、実際にそれらを処理し、独自のイベントを発生させるソリューションがあります。いくつかのプロパティを追加するだけでも大変な作業です...