[英]how to check if a class implements and interface with a generic using c#?
我有以下界面
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>
扩展了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>
我该如何正确修复此错误?
您已经知道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)
{
// ...
}
}
}
这是一个例子,如果Announce不是通用的
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)
{
// ...
}
}
}
此代码不起作用
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess<Event> _cls)
{
_cls.Finished(_event, cls);
}
因为cls
的类型为SendConfirmationEmail()
,它实现了Listener<UserWasUpdated>
而_cls
则被转换为IHandleSuccess<Event>
。 函数_cls.Finished()
期望一个Listener<Event>
类型的参数listener
Listener<Event>
,而不是Listener<UserWasUpdated>
你的函数有什么用? Finished(UserWasUpdated _event, Listener<UserWasUpdated> listener)
? 查看您使用它的方式,您可以删除parameterc 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);
}
如果您希望能够这样做,则需要使界面非通用。 如果事先已知对象cls
_event
对象,则可以将其存储并在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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.