C# 接口代理的编译时检查
一点背景 我有一个接受“处理程序”的类,如下所示:C# 接口代理的编译时检查,c#,class,interface,behavior,C#,Class,Interface,Behavior,一点背景 我有一个接受“处理程序”的类,如下所示: interface IHandler { void DoSomething(MyType type, string s); } public class MyType { private IHandler handler; public MyType(IHandler handler = null) { this.handler = handler; } public voi
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
,该参数将在处理程序调用中用this
填充
我的问题
有没有一种模式允许这样的事情发生?我曾想过继承MyType
中的IHandler
,但这要求调用者在调用中指定类型,这与目的背道而驰。我还可以确保它们都是手动调用的,但是接口将变得非常庞大,并且可能有两个父接口。这是我最后的办法。如果需要的话,我真的不介意修改代码
这是我的目标
我希望能够在
MyType
类中添加行为,同时允许处理程序为null(不添加行为)。我选择了这种模式,但我只是在规划代码,所以更改任何能提供这组功能的东西都会很好。为什么MyType
本身要实现它不继承的接口方法?如果必须使用另一组方法添加IAnotherHandler
,该怎么办
MyType
看起来像是调用IHandler
方法而不指定MyType
的包装器。如果处理程序是由MyType
创建的,那么您可以将this
作为构造函数参数传递(为了保持封装,没有它,您只需创建一个属性来分配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
在不修改大部分代码的情况下,向handler添加更多方法或向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
的实例。如果您将其更改为DoSomething(字符串s),该怎么办
那么,当您在MyType
中实现它时,您不需要传递MyType
的实例,因为它是MyType
?@juharr,因为IHandler
可能处理多种类型的MyType
,我需要知道它在IHandler
方法中是哪一个听上去,你和我一起生活可能会更好。我仍然不能完全确定你想要实现什么。
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);
}