如何使用c#检查类是否实现并与泛型接口?
我有以下接口如何使用c#检查类是否实现并与泛型接口?,c#,C#,我有以下接口 public interface IHandleSuccess<T> where T : Event { void Finished(T _event, Listener<T> listener); } 但是,行IHandleSuccess给了我一个错误 意外使用未绑定的泛型名称 由于泛型参数将始终扩展事件类,因此我还尝试将代码更改为以下内容 listener.Handle(_event); if (listener is IHandleSucc
public interface IHandleSuccess<T> where T : Event
{
void Finished(T _event, Listener<T> listener);
}
但是,行IHandleSuccess
给了我一个错误
意外使用未绑定的泛型名称
由于泛型参数将始终扩展事件
类,因此我还尝试将代码更改为以下内容
listener.Handle(_event);
if (listener is IHandleSuccess<Event> _listener)
{
_listener.Finished(_event, listener);
}
listener.Handle(\u事件);
if(侦听器是IHandleSuccess\u侦听器)
{
_listener.Finished(_事件,listener);
}
但是\u listener.Finished(\u event,listener)
给了我以下错误
第二个参数无法从Listener
转换为Listener
如何正确修复此错误?您已经知道
IHandleSuccess
的一般类型是什么,它将是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 annound(T_事件),其中T:event
{
IEnumerable侦听器=Container.ResolveAll()
foreach(侦听器中的var侦听器)
{
尝试
{
句柄(_事件);
if(侦听器是IHandleSuccess\u侦听器)
{
_listener.Finished(_事件,listener);
}
}
捕获(例外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)
{
// ...
}
}
}
public作废公告(Foo\u事件)
{
IEnumerable侦听器=Container.ResolveAll()
foreach(侦听器中的var侦听器)
{
尝试
{
句柄(_事件);
if(侦听器是IHandleSuccess\u侦听器)
{
_listener.Finished(_事件,listener);
}
}
捕获(例外e)
{
// ...
}
}
}
这个代码不起作用
var cls = new SendConfirmationEmail();
if (cls is IHandleSuccess<Event> _cls)
{
_cls.Finished(_event, cls);
}
实施方式如下:
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()
}
}
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();
}
}
实施方式如下:
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()
}
}
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();
}
}
我绝对不是一个C#专家,但这不能通过反思来实现吗?只是大声想一想。使用IoC容器解决了这个问题,因此实现会发生变化,这破坏了设计,因此是糟糕的设计。这与您的设计有什么根本不同?那么,当您使用IoC容器时,cls的预期编译时间类型或接口是什么?以代码形式向我们展示在使用容器时如何获得cls
。如果可能,请避免使用var
,并在此更新的示例中使用显式类型名称。@MikeA正如我在更新我的评论时提到的,请将var
的所有用法替换为var将使用的类型,我需要知道GetListerners()的确切返回类型
它看起来像一个列表
,但我不想做假设,非常感谢你。真不敢相信是这样simple@MikeA请通读他提出的一些好的观点,比如在函数中的任何地方传递cls
in都是不必要的,在你的void中使用listener
(T\u事件,listener-listener)代码>函数可以替换为一个简单的this.
调用。此时,您是否同意我应该放弃IHandleSuccess,而是在我的Listener
类中添加一个名为Finished
的虚拟方法?如果Listener
的任何实现需要实现Finished
我会将其移到Listener
是。
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);
}
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();
}