我正在为“可运行”的东西制作一个微型框架。 (它们是实验,测试,任务等)
// 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 = ??)我通过向
IA<T>
添加刚刚指定类型参数的另一个接口(interface)来纠正#1:interface IBlockRunner : IRunnableOf<Block> { }
并将我的
ConcurrentBlockRunner
和SequentialBlockRunner
定义修改为:class ConcurrentBlockRunner : SequentialRunner<Block>, IBlockRunner
class SequentialBlockRunner : ConcurrentRunner<Block>, IBlockRunner
由于
ConcurrentBlockRunner
和SequentialBlockRunner
都使用Block
作为其类型参数,因此这似乎是正确的解决方案。但是,我不禁对此感到“怪异”,因为好吧,我只是添加了该界面。对于#2,我想在
ConcurrentBlockRunner
和SequentialBlockRunner
中添加几个通用数据。有几个属性适用于它们,但不适用于它们唯一的公共(public)基类,这些属性一直存在于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中,一切都会正常进行。有没有更好的办法?
我知道我将立即建议我考虑开始使用composition:
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
参数的类型为SequentialBlockRunner
。但是,事件处理程序试图将其强制转换为BlockRunner
类型,这当然会失败。那里的解决方案不是使用add
/remove
代理事件,而是实际处理它们并引发我自己的事件。要做很多工作只是添加几个属性... 最佳答案
Composition over Inheritance,FTW!
更明确地说:
class SequentialRunner<T> : RunnerBase<T>
应该实现
IRunnableOf<T>
并代理RunnerBase<T>
而不继承它。class SequentialRunner<T> : IRunnableOf<T>
{
private readonly RunnerBase<T> _runnerBase;
...
}
关于c# - 如何处理C#中缺少多重继承的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10988695/