【问题标题】:Compile time checks for interface proxy接口代理的编译时间检查
【发布时间】:2016-03-24 14:14:59
【问题描述】:

一点上下文

我有一个接受“处理程序”的类,如下所示:

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

我的问题

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

我的目标

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

【问题讨论】:

  • 如果您将其更改为DoSomething(string s),那么当您在MyType 中实现它时,您不需要传递MyType 的实例,因为它是MyType
  • @juharr 因为IHandler 可能会处理多种类型的MyType,我需要知道它在IHandler 方法中是哪一种! :)
  • 听起来你可能会更好地使用generics。我仍然不完全确定您要达到的目标。

标签: c# class interface behavior


【解决方案1】:

为什么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);
}

【讨论】:

  • 我认为重点是MyType 的实例将作为第一个参数传入。
  • @juharr,见编辑。它通过在 MyType 中不必要地包装 IHandler 方法并删除需要为每个处理程序方法传递 MyType 的实例来解决初始问题(我首先回答)。
猜你喜欢
  • 2011-01-06
  • 1970-01-01
  • 2015-02-11
  • 2020-02-07
  • 2020-01-07
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
相关资源
最近更新 更多