我具有以下界面
public interface IHandleSuccess<T> where T : Event
{
void Finished(T _event, Listener<T> listener);
}
以及以下课程
public abstract class Listener<T> where T : Event
{
public abstract void Handle(T _event);
}
下面的类扩展了Listener<T>
并且实现了IHandleSuccess<T>
public class SendConfirmationEmail : Listener<UserWasUpdated>, IHandleSuccess<UserWasUpdated>
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
public void Finished(UserWasUpdated _event, Listener<UserWasUpdated> listener)
{
// ...
}
}
最后,另一个侦听器扩展了Listener<T>
但未实现IHandleSuccess<T>
public class ScheduleOriantation: Listener<UserWasUpdated>
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
}
应用启动时,我的SendConfirmationEmail
获取类已注册到我的IoC
容器中。
我想检查已解决的实例是否实现了合同。如果可以,我想调用Finished
方法。
public void Announce<T>(T _event) where T : Event
{
IEnumerable<Listener<T>> listeners = Container.ResolveAll<Listener<T>>()
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<Event> _listener)
{
_listener.Finished(_event, listener);
}
但是_listener.Finished(_event, listener)
给我以下错误
第二个参数不能从
Listener<T>
转换为Listener<Event>
如何正确纠正此错误?
答案 0 :(得分:5)
您已经知道IHandleSuccess<>
的通用类型,它将是T
,因为您声明将从请求中接收Listener<T>
。
public void Announce<T>(T _event) where T : Event
{
IEnumerable<Listener<T>> listeners = Container.ResolveAll<Listener<T>>()
foreach (var listener in listeners)
{
try
{
listener.Handle(_event);
if (listener is IHandleSuccess<T> _listener)
{
_listener.Finished(_event, listener);
}
}
catch (Exception e)
{
// ...
}
}
}
以下是“公告”不是通用的示例
public void Announce(Foo _event)
{
IEnumerable<Listener<Foo>> listeners = Container.ResolveAll<Listener<Foo>>()
foreach (var listener in listeners)
{
try
{
listener.Handle(_event);
if (listener is IHandleSuccess<Foo> _listener)
{
_listener.Finished(_event, listener);
}
}
catch (Exception e)
{
// ...
}
}
}
答案 1 :(得分:5)
这段代码不起作用
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess<Event> _cls)
{
_cls.Finished(_event, cls);
}
因为cls
的类型为SendConfirmationEmail()
,它实现了Listener<UserWasUpdated>
,而_cls
被强制转换为IHandleSuccess<Event>
。
函数_cls.Finished()
期望类型为listener
而不是Listener<Event>
Listener<UserWasUpdated>
函数Finished(UserWasUpdated _event, Listener<UserWasUpdated> listener)
的用途是什么?
查看使用它的方式,可以删除参数c listener
并使用this
引用当前的侦听器:
所以界面看起来像这样:
public interface IHandleSuccess<T> where T : Event
{
void Finished(T _event);
}
实施方式如下:
public class SendConfirmationEmail : Listener<UserWasUpdated>, IHandleSuccess<UserWasUpdated>
{
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<UserWasUpdated>, 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();
}
答案 2 :(得分:-1)
您可以使用Type.GetInterfaces()
并执行以下操作:
if (listener.GetType().GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IHandleSuccess<>)))
{
//
}