作者:余逮月笑下死手 | 来源:互联网 | 2022-12-01 20:02
我有以下界面
public interface IHandleSuccess where T : Event
{
void Finished(T _event, Listener listener);
}
以下课程
public abstract class Listener where T : Event
{
public abstract void Handle(T _event);
}
以下类扩展Listener
和实现IHandleSuccess
public class SendConfirmationEmail : Listener, IHandleSuccess
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
public void Finished(UserWasUpdated _event, Listener listener)
{
// ...
}
}
最后,另一个扩展Listener
但未实现的侦听器IHandleSuccess
public class ScheduleOriantation: Listener
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
}
应用程序启动时,我的SendConfirmationEmail
获取类已注册到我的IoC
容器中.
我想检查已解析的实例是否实现了合同.如果确实如此,我想调用该Finished
方法.
public void Announce(T _event) where T : Event
{
IEnumerable> listeners = Container.ResolveAll>()
foreach (var listener in listeners)
{
try
{
listener.Handle(_event);
if (listener is IHandleSuccess<> _listener)
{
_listener.Finished(_event, listener);
}
}
catch (Exception e)
{
// ...
}
}
}
但是,这条线IHandleSuccess<>
给了我一个错误
意外使用未绑定的通用名称
由于泛型参数将始终扩展Event
类,我还尝试将代码更改为以下内容
listener.Handle(_event);
if (listener is IHandleSuccess _listener)
{
_listener.Finished(_event, listener);
}
但是_listener.Finished(_event, listener)
给我以下错误
第二个参数无法转换Listener
为Listener
我该如何正确修复此错误?
1> Scott Chambe..:
您已经知道通用类型是什么IHandleSuccess<>
,这将是T
因为您声明您将从Listener
请求中接收.
public void Announce(T _event) where T : Event
{
IEnumerable> listeners = Container.ResolveAll>()
foreach (var listener in listeners)
{
try
{
listener.Handle(_event);
if (listener is IHandleSuccess _listener)
{
_listener.Finished(_event, listener);
}
}
catch (Exception e)
{
// ...
}
}
}
这是一个例子,如果Announce不是通用的
public void Announce(Foo _event)
{
IEnumerable> listeners = Container.ResolveAll>()
foreach (var listener in listeners)
{
try
{
listener.Handle(_event);
if (listener is IHandleSuccess _listener)
{
_listener.Finished(_event, listener);
}
}
catch (Exception e)
{
// ...
}
}
}
@MikeA请阅读[bodin的回答](/sf/ask/17360801/)他做了一些好点,比如传递`cls` in unessesary,在你使用`listener`的函数中的任何地方void Finished(T _event,Listener
listener);`函数可以用简单的`this`调用替换.
2> 小智..:
此代码不起作用
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess _cls)
{
_cls.Finished(_event, cls);
}
因为cls
是SendConfirmationEmail()
实现的类型Listener
而是_cls
被铸造的类型IHandleSuccess
.该函数需要_cls.Finished()
一个listener
类型的参数Listener
,而不是Listener
你的功能有Finished(UserWasUpdated _event, Listener listener)
什么用?查看您使用它的方式,您可以删除参数listener
c并使用this
以下内容引用当前侦听器:
所以界面看起来像这样:
public interface IHandleSuccess where T : Event
{
void Finished(T _event);
}
和这样的实现:
public class SendConfirmationEmail : Listener, IHandleSuccess
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
public void Finished(UserWasUpdated _event)
{
// Call whatever function on your object
this.Cleanup()
}
}
要回答第一个问题,这不起作用,因为泛型的每次使用都是不同的类型:
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess<> _cls)
{
// _event and cls types can't be resolved at compilation time here:
_cls.Finished(_event, cls);
}
如果您希望能够这样做,则需要使界面非通用.如果_event
对象cls
事先为您的对象所知,您可以将其存储并在Finished()
调用中使用它,如下所示:
接口:
public interface IHandleSuccess
{
void Finished();
}
和这样的实现:
public class SendConfirmationEmail : Listener, IHandleSuccess
{
private _Event = null;
public override void Handle(UserWasUpdated _event)
{
// Store _event
_Event = _event;
}
public void Finished()
{
// Call whatever function on your object
this.Cleanup()
// Call whatever is needed on _event
_Event?.Cleanup();
}
}
然后你可以这样做:
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess _cls)
{
_cls.Finished();
}