首页 > 其他分享 >无法将delegate(委托)转换为泛型类型T

无法将delegate(委托)转换为泛型类型T

时间:2022-10-29 20:47:32浏览次数:67  
标签:delegate 委托 delegateType object CreateDelegate typeof 为泛 类型 Delegate

为什么我们不能将委托的实例强制转换为通用类型T

考虑一个实用程序方法CreateDelegate,它创建一个T实例,它是一个委托,即从MulticastDelegate派生的类型。

 T CreateDelegate<T>() {… }

不幸的是,泛型不允许将T约束到从MulticastDelegate 派生的类型,从而产生以下编译错误:

  约束不能是特殊类'System.MulticastDelegate'

然而,此实用程序方法检查T是否与MulticastDelegate兼容,并通过Delegate::CreateDelegate反射创建代理。但是,如果我们尝试将Delegate::CreateDelegate的结果转换为T,我们将收到以下编译错误:

  无法将类型'System.Delegate'转换为'T'

但是,如果我先将其投放到object然后投放到T,它会正常工作:

T h = (T) ((object) Delegate.CreateDelegate(typeof(T), target, m));

为什么我们不能直接将代表委托给T?

 

 

 

1 个答案:

 

答案 0 :(得分:10)

C#语言强制静态检查从类型X到类型Y的强制转换是否有效 - 即它是否使有意义,因为编译器可以(在某种程度上)保证兼容性并拒绝错误在编译时清楚。不受约束的泛型类型TSystem.Delegate没有任何直接的共同点。但是,当转换为object时,编译器知道每个类型实际上都是object,因此它允许转换。这并不意味着在特定情况下运行时类型检查不会失败。

as运算符更宽松一点,因为它不会导致其他无效转换的异常。编译器在应用静态检查时也不那么严格。在您的特定情况下,这很有用,因为您可以省略object的中间演员并使用as T。但是,需要的是as仅适用于类类型,因此您必须应用where T : class约束。

所以这个方法看起来像这样(简化):

public T CreateDelegate<T>(…) where T : class
{
    return Delegate.CreateDelegate(typeof(T), …) as T;
}

正如@usr建议的那样,推荐读物是Eric Lippert的博客,例如: this article on casts and type parameters

 

 

出处:https://www.thinbug.com/q/35321586

==================================================================

个人总结,判断泛型是否为delegate类型

我们根据自己代码的情况进行判断,主要是依据运算符 is、as 、IsSubclassOf、IsAssignableFrom等,具体的可以看我前面的相关文章的介绍。

例如:

        private static T GetMethodDelegate<T>() where T : class
        {
            T res = default(T);
            Type delegateType = typeof(T);
            bool isDelegateType = delegateType is Delegate;
            var s1 = delegateType.IsAssignableFrom(typeof(Delegate));
            var s2 = typeof(Delegate).IsAssignableFrom(delegateType);
            var s3 = typeof(Delegate).IsSubclassOf(delegateType);
            var s4 = delegateType.IsSubclassOf(typeof(Delegate));
            if (isDelegateType)
            {
                DynamicMethod dynamicSpeakWithCall = new DynamicMethod("D", null, new[] { typeof(int) });//res = dynamicSpeakWithCall.CreateDelegate(typeof(T)) as T;
            }
            return res;
        }

 

标签:delegate,委托,delegateType,object,CreateDelegate,typeof,为泛,类型,Delegate
From: https://www.cnblogs.com/mq0036/p/16839788.html

相关文章

  • 使用delegate给方法传递参数,或返回delegate对象
    第一次在博客园写文章。最近遇到一个问题,用到了多线程,以前用的时候线程启动时不需要传递参数,可现在需要时却被难了一把。。还是先说说delegate吧delegate是C#中的一种......
  • UEC 利用代理/委托写一个生命组件
    首先基于ActorComponent创建一个组件HealthComponent,将需要的变量与函数创建#include"CoreMinimal.h"#include"Components/ActorComponent.h"#include"HealthCompo......
  • C#新语法进阶委托泛型LinqLambda表达式
    学习C#开发的程序员们,相信大家也有自己的困惑。C#对于我们来说,一会很熟悉,一会很陌生,当你熟悉的时候,你阅读源码能一目十行,当你很陌生的时候,你十天能看懂一行代码。我们总是伴......
  • C#中的委托delegate和Lambda表达式
    委托:委托别人去帮我完成某件事情。自定义委托AddDelegateAD=newAddDelegate(Add);//获取需要委托的方法详细,参数返回值和定义委托参数返回值都必须一样。stringst......
  • .NET基础知识-常量、字段、属性、特性与委托
    引用网址:http://t.zoukankan.com/hypo106-p-13467360.html常量:const关于常量的几个特点总结一下:常量的值必须在编译时确定,简单说就是在定义是设置值,以后都不会被改......
  • iOS基础 - SceneDelegate
    前言1-自从Xcode11发布以来,当你使用新XCode创建一个新的iOS项目时SceneDelegate会被默认创建2-在iOS13后SceneDelegate将负责AppDelegate的某些功能......
  • 委托+继承_c++
    ......
  • JS事件冒泡与事件委派(委托)
    学到了学到了看了这篇后博客后,对事件冒泡和事件委托有了清晰的理解https://blog.csdn.net/weixin_48769418/article/details/115045810 一、事件冒泡指的是事件的......
  • 18.ansible delegate_to
    1.场景介绍在对一组服务器server_group1执行操作过程中,需要在另外一台机器A上执行一个操作,比如在A服务器上添加一条hosts记录,这些操作必须要在一个playbook联......
  • 事件委托
    什么是事件委托?由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,种方法叫做“事件代理”,也......