热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用c#检查类是否实现并与泛型接口?

如何解决《如何使用c#检查类是否实现并与泛型接口?》经验,为你挑选了2个好方法。

我有以下界面

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)给我以下错误

第二个参数无法转换ListenerListener

我该如何正确修复此错误?



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);
}

因为clsSendConfirmationEmail()实现的类型Listener而是_cls被铸造的类型IHandleSuccess.该函数需要_cls.Finished()一个listener类型的参数Listener,而不是Listener

你的功能有Finished(UserWasUpdated _event, Listener listener)什么用?查看您使用它的方式,您可以删除参数listenerc并使用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();
}


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 热血合击脚本辅助工具及随机数生成器源码分享
    本文分享了一个热血合击脚本辅助工具及随机数生成器源码。游戏脚本能够实现类似真实玩家的操作,但信息量有限且操作不可控。热血合击脚本辅助工具可以帮助玩家自动刷图、换图拉怪等操作,并提供了雷电云手机的扩展服务。此外,还介绍了使用mt_rand函数作为随机数生成器的代码示例。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
author-avatar
余逮月笑下死手
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有