2016-03-24 101 views
0

上下文的位编译时检查

我有一个类,它在“处理程序”,像这样:

interface IHandler 
{ 
    void DoSomething(MyType type, string s); 
} 

public class MyType 
{ 
    private IHandler handler; 

    public MyType(IHandler handler = null) 
    { 
     this.handler = handler; 
    } 

    public void DoSomething(string s) 
    { 
     handler?.DoSomething(this, s); 
    } 
} 

问题

我要确保IHandler中的所有方法都在MyType中执行,而不需要第一个参数MyType type,这将填充到我与this处理程序调用。

我的问题

是否有允许这样的事情的模式?我想从IHandler继承MyType,但这需要调用者指定在调用中的类型,这打破了目的。我也可以确保它们都被手动调用,但接口将变得非常庞大,并且可能会有一些父接口。这是我最后的手段。如果需要的话,我并不介意更改代码。

我这个

目标,我希望能够在MyType类添加行为,同时允许处理器为空(不添加行为)。我选择了这种模式,但我只是在计划代码,所以改变任何可以给我这些功能的东西都会很棒。

+0

如果你把它改成'DoSomething的(字符串s)'然后当你实现它在'MyType'你不需要通过MyType的一个实例,因为它是一个MyType? – juharr

+0

@juharr由于IHandler可能处理多种类型的MyType,我需要知道它在'IHandler'方法中的哪一个! :) –

+0

这听起来像你可能会更好[泛型](https://msdn.microsoft.com/en-us/library/512aeb7t.aspx0)。我仍然不完全确定你想要达到的目标。 – RoadieRich

回答

0

为什么MyType本身实现了它不会继承的接口方法?如果你不得不添加IAnotherHandler与另一套方法?

MyType看起来像一个包装,呼吁IHandler方法没有指定MyType。如果处理程序由MyType创建的,那么你可以传递this作为构造参数(保持密封,没有它,你可以简单地做一个财产分配this

public class MyType 
{ 
    public IHandler Handler { get; } 

    public MyType() { } 

    public MyType(IHandlerFactory factory) 
    { 
     // create instance via factory 
     Handler = factory.CreateHandler(this); 
    } 
} 

现在你应该可以通过属性来调用处理方法:

var test = new MyType(new ConcreteFactory()); // with handler 
// var test = new MyType(); // without handler 
test.Handler?.DoSomething("test"); // you will have to check for `null` always 

它应该很容易更多的方法来处理以上的处理程序添加到MyType而不需要修改太多的代码。


我会用基类的处理程序:

abstract class Handler 
{ 
    MyType _type; 

    public Handler(MyType type) 
    { 
     Type = type; 
    } 

    public abstract void DoSomething(string s) { ... } 
} 

class ConcreteHandler: Handler 
{ 
    public override void DoSomething(string s) { ... } 
} 

interface IHandlerFactory 
{ 
    Handler CreateHandler(MyType type); 
} 

class ConcreteFactory: IHandlerFactory 
{ 
    public Handler CreateHandler(MyType type) => new ConcreteHandler(type); 
} 
+0

我认为关键是'MyType'的实例会作为第一个参数传入。 – juharr

+0

@juharr,请参阅编辑。它解决了最初的问题(我首先回答了这个问题),在'MyType'中不必要地包装了'IHandler'方法,并且为每个处理方法移除了需要传递'MyType'的实例。 – Sinatr