[英]how to check if a class implements and interface with a generic using c#?
I have the following interface 我有以下界面
public interface IHandleSuccess<T> where T : Event
{
void Finished(T _event, Listener<T> listener);
}
And the following class 以下课程
public abstract class Listener<T> where T : Event
{
public abstract void Handle(T _event);
}
The following class which extends Listener<T>
and implements IHandleSuccess<T>
以下类扩展了
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)
{
// ...
}
}
Lastly, another listener that extends Listener<T>
but does not implement IHandleSuccess<T>
最后,另一个监听
Listener<T>
扩展了Listener<T>
但没有实现IHandleSuccess<T>
public class ScheduleOriantation: Listener<UserWasUpdated>
{
public override void Handle(UserWasUpdated _event)
{
// ...
}
}
My SendConfirmationEmail
gets class is registered into my IoC
container when the application starts up. 我的
SendConfirmationEmail
获取类在应用程序启动时注册到我的IoC
容器中。
I want to check if the resolved instance implements a contract. 我想检查已解析的实例是否实现了合同。 And if it does, I want to call the
Finished
method. 如果确实如此,我想调用
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)
{
// ...
}
}
}
However, the line IHandleSuccess<>
is giving me an error 但是,
IHandleSuccess<>
行给了我一个错误
Unexpected use of an unbound generic name
意外使用未绑定的通用名称
Since the generic argument will always extend the Event
class, I also tried changing the code to the following 由于泛型参数将始终扩展
Event
类,我还尝试将代码更改为以下内容
listener.Handle(_event);
if (listener is IHandleSuccess<Event> _listener)
{
_listener.Finished(_event, listener);
}
But _listener.Finished(_event, listener)
gives me the following error 但是
_listener.Finished(_event, listener)
给了我以下错误
The second argument cannot convert from
Listener<T>
toListener<Event>
第二个参数无法从
Listener<T>
转换为Listener<Event>
How can I correctly fix this error? 我该如何正确修复此错误?
You already know what the generic type of IHandleSuccess<>
will be, it will be T
because you declared that you would be receiving Listener<T>
's from the request. 您已经知道
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)
{
// ...
}
}
}
Here is a example if Announce was not generic 这是一个例子,如果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)
{
// ...
}
}
}
This code doesn't work 此代码不起作用
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess<Event> _cls)
{
_cls.Finished(_event, cls);
}
Because cls
is of type SendConfirmationEmail()
which implements Listener<UserWasUpdated>
whereas _cls
is casted as IHandleSuccess<Event>
. 因为
cls
的类型为SendConfirmationEmail()
,它实现了Listener<UserWasUpdated>
而_cls
则被转换为IHandleSuccess<Event>
。 The function _cls.Finished()
expect a parameter listener
of type Listener<Event>
, not Listener<UserWasUpdated>
函数
_cls.Finished()
期望一个Listener<Event>
类型的参数listener
Listener<Event>
,而不是Listener<UserWasUpdated>
What is the use of your function Finished(UserWasUpdated _event, Listener<UserWasUpdated> listener)
? 你的函数有什么用?
Finished(UserWasUpdated _event, Listener<UserWasUpdated> listener)
? Looking at the way you are using it, you could remove the parameterc listener
and reference the current listener using this
: 查看您使用它的方式,您可以删除parameterc
listener
并使用this
引用当前侦听器:
So the interface would look like this: 所以界面看起来像这样:
public interface IHandleSuccess<T> where T : Event
{
void Finished(T _event);
}
And the implementation like this: 和这样的实现:
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()
}
}
To answer you first question, this doesn't work because each use of the generic is a different type: 要回答第一个问题,这不起作用,因为泛型的每次使用都是不同的类型:
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);
}
If you want to be able to do this, you need to make you interface non generic. 如果您希望能够这样做,则需要使界面非通用。 If the
_event
object is known by your object cls
beforehand, you can store it and use it in the Finished()
call, like this: 如果事先已知对象
cls
_event
对象,则可以将其存储并在Finished()
调用中使用它,如下所示:
Interface: 接口:
public interface IHandleSuccess
{
void Finished();
}
And the implementation like this: 和这样的实现:
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();
}
}
You can then do: 然后你可以这样做:
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess _cls)
{
_cls.Finished();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.