获取提供给泛型方法的泛型参数类型和值

2023-11-26

如何获取提供给封闭/构造泛型方法的参数值?

已经有一段时间没有接触Reflection了。所有这些都曾经是我的,嗯,无论如何。

class Program
{
    static void Main(string[] args)
    {
        new ConcreteFoo().GenericMethod<int>(5);
        Console.ReadKey();
    }
}

class ConcreteFoo
{
    public void GenericMethod<Q>(Q q) 
    {
        var method = MethodInfo.GetCurrentMethod();    
        var parameters = method.GetParameters();    
        if (parameters.Length > 0)
            foreach (var p in parameters)
                Console.WriteLine("Type: {0}", p.ParameterType);

        // That still prints Q as the type. 
        // I've tried GetGenericArguments as well. No luck.                
        // I want to know:
        // 1) The closed type, i.e. the actual generic argument supplied by the caller; and
        // 2) The value of that argument
    }

    public void GenericMethodWithNoGenericParameters<Q>() 
    { 
        // Same here
    }
}

class GenericFoo<T>
{
    public void NonGenericMethod(T t) { /* And here*/ }  
    public void GenericMethod<Q>(Q q) { /* And here */ }
}

UPDATE

这个问题很荒谬,因此被提问者关闭。他希望保留它,只是为了让他的孩子们看看,如果他们最终成为 C# 程序员,爸爸是多么愚蠢。


简短的答案是 typeof(Q)。

长答案(试图解释为什么你不能枚举这些类型并且必须专门编写它们)如下所示:

每个通用方法(比它声明的类更通用)都有对应的、不同的 MethodInfo 实例(用于其所有(曾经)接触过的详细信息)和另一个用于“模板”/打开方法的 MethodInfo 实例。

您可以使用它来获得您想要的东西:

class ConcreteFoo {    
   public void GenericMethod<Q>(Q q) {
     var method = MethodInfo.GetCurrentMethod();
     var closedMethod = method.MakeGenericMethod(typeof(Q));

     // etc
   }
}

这是为什么 ? 这是因为反射中的“枚举操作”都不会返回引用封闭详细化的 MethodInfo 实例。

如果您像这样枚举 ConcreteFoo 声明的静态方法:

var atTime1 = typeof(ConcreteFoo).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

ConcreteFoo.GenericMethod( true );

var atTime2 = typeof(ConcreteFoo).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

你会得到相同的结果。 就泛型方法及其具体化而言,您将仅获得与泛型方法(开放变体)关联的反射对象。

atTime2 将不包含引用新编译的 GenericMethod 的额外 MethodInfo。

但这并不是一件坏事,不是吗? GetMethods() 应返回一致的结果,并且其结果不会随时间变化。 当涉及到“导航”操作时,泛型方法的代数实际上非常好:

  1. 所有打开的 MethodInfo 都具有 IsGenericMethod = true 和 IsGenericMethodDefinition = true
  2. 所有关闭的 MethodInfo 都具有 IsGenericMethod = true 和 IsGenericMethodDefinition = false
  3. 通过在封闭的 MethodInfo 上调用 .GetGenericMethodDefinition(),您可以获得开放的 MethodInfo
  4. 通过在开放的 MethodInfo 上调用 .MakeGenericType(params Type[] types) ,您可以获得所需的任何封闭类型(在语法上不知道这些类型是什么,并且有可能因不尊重 where 子句而收到异常)

对于来自当前线程的角度(而不是从程序集和类型的角度)的反射操作也是如此:

MethodBase MethodInfo.GetCurrentMethod()

and

StackTrace trace = new StackTrace();
IEnumerable<MethodBase> methods = from frame in trace.GetFrames()
                                  select frame.GetMethod();

从不返回泛型方法的实际封闭变体(如果有) 实际上位于顶部或整个当前调用堆栈。

在某种程度上,你的问题并不荒谬,因为,在这种情况下获取当前方法你可以轻松地将其替换为获取当前方法 plus 生成通用方法加上语法上可用的类型(随便),你不能这样说你的来电者。

因此......对于非泛型方法,您始终可以查看堆栈并准确了解这些方法的参数类型。相互调用的方法,最终你的方法被调用......但是对于通用方法(它们确实是真正封闭的,因为我重复一遍,认为运行并调用另一个方法并被其他人调用的通用方法是不合逻辑的(等等) )是一个开放的)你无法找出参数的类型,就像你无法了解任何此类方法的局部变量的值一样(它们是确定性的,但使其成为性能上的一个很大的缺陷可能性)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取提供给泛型方法的泛型参数类型和值 的相关文章

  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 为什么极端下派生类(多重虚拟继承)的大小包括超类成员大小的两倍?

    include
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 使用 C# 读取 Soap 消息

  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类

随机推荐

  • 在 Azure Functions 中使用 Python 3

    我的目标是让一些 Python 3 代码作为 Azure Functions 运行 但我无法让 Python 3 工作 我意识到 Azure Functions 中的 python 支持仍处于实验阶段 这是我尝试过的 创建一个新的函数应用程
  • Flutter“不要跨异步间隙使用 BuildContext”

    基本上 当用户在对话框中按 注销 时 我想返回到我的登录视图 onSelected value async switch value case MenuAction logout final shouldLogout await showL
  • SqlCommand.CommandTimeout 和 SqlConnection.ConnectionTimeout 之间有什么区别?

    有什么区别吗SqlCommand CommandTimeout and SqlConnection ConnectionTimeout在 NET 中 Yes CommandTimeout是单个命令需要多长时间才能完成 ConnectionT
  • Pandas - 按一列分组并聚合其他列以列出

    我有一个数据框 其中有多个用户条目 这些用户还可以分配给多个 ID 我想按用户进行分组 然后将这些 ID 的列表存储在另一列中 如下所示 我想从这里开始 df1 pd DataFrame USER BOB STEVE PAUL KEITH
  • dispatch_set_target_queue如何工作?

    由于缺乏材料dispatch set target queue 我来这里寻求帮助 所以谢谢 这是我的测试代码 dispatch queue t mySerialDispatchQueue1 dispatch queue create com
  • 阻止 Visual Studio 2013 自动删除分配中的多余空格

    我正在尝试对齐一些分配以提高可读性 但每次我粘贴某些内容时 Visual Studio 2013 都会自动删除前面的多余空格 例如 这个 static class Constants public static string Somethi
  • 这些何时加载 DLL:隐式链接 VS 显式链接

    我认为隐式链接会在应用程序启动时立即加载 DLL 因为它也称为 加载时动态链接 但我从这里的链接中发现了下面一些奇怪的解释 https msdn microsoft com en us library 253b8k2c VS 80 aspx
  • 防止 C# 应用程序运行多个实例

    我用c 写了一个程序 现在我想知道阻止程序启动 如果它已经在运行 的正确方法是什么 因此 如果它已经在运行 则双击该程序它将不会启动 因为它已经在运行 我可以做到这一点 但我正在考虑一个标准且正确的方法 推荐的方法是使用系统互斥锁 bool
  • 如何使用CasperJS在没有表单标签的情况下填写表单

    我是 CasperJS 新手 在登录该网站时遇到问题http weibo com login php 这是我尝试过的 this fill form contact form username email protected password
  • 如何在 Jupyter Notebook 中显示文件中的图像?

    我想用一个IPython笔记本作为一种交互式分析我用 Biopython 制作的一些基因组图表的方法GenomeDiagram模块 虽然有大量关于如何使用的文档matplotlib为了在 IPython 笔记本中获得内联图形 GenomeD
  • 意外的 strtok() 行为

    我正在尝试使用 strtok 计算文件中的单词数 code c WHAT Use strtok to count the number of words in a file include
  • 使用Python的unittest模块作为测试运行程序时,如何在测试之前运行初始化代码?

    在运行库提供的测试之前 库的用户如何运行自己的初始化代码 例如设置记录器的调试级别 蟒蛇的unittest模块用作测试运行器 您可以尝试使用 pytest 来运行单元测试 如果这有效 许多基于单元测试的测试套件都有效 那么您可以创建一个小模
  • 如何使用 Powershell 删除 IIS 自定义标头?

    我正在编写一个将网站部署到 IIS 7 的 powershell 脚本 我想使用 powershell 中的 Web 管理模块而不是使用 appcmd 执行以下命令来删除自定义标头 如何在不使用 appcmd 的 powershell 中执
  • 在 bash 中回显打印 -e

    我已经得到了在 Bash 中创建的脚本 我正在使用的功能之一是echo我正在使用 e解释标志 反斜杠转义 我有一个以彩色打印文本的脚本 但是当它回显将要以彩色显示的消息时 它也会打印 e带有消息的标记 此处为例 NC 033 31 0m n
  • 如何取消或停止 Google App Engine Cron 作业

    我将一个使用 CRON 作业的应用程序部署到我的 Google App Engine 我跟着this教程 它工作正常 我可以在我的 GAE 控制台中确认它 在我的 Stackdriver 日志中 我还可以看到 CRON 作业正在运行 但我对
  • 尝试在 Lumen 中重置密码

    我正在尝试在 Lumen 中实现密码重置功能 但未能成功 Lumen 可以访问 Laravel 之类的东西密码经纪商 and 密码管理器但我无法使用它并成功 有没有什么解决办法呢 我昨晚才真正弄清楚这一点 并写了一篇关于它的博客 http
  • 布局内的 OpenGL 视图

    如何设置包含 OpenGL 视图的 xml 布局 我现在所做的就是使用 setContentView 将 OpenGL 视图设置为唯一的视图 但我想创建一个包含 OpenGL 视图的 xml 布局 假设我主要想要 OpenGL 视图 并在底
  • 当用户在 jquery 中按 Enter 键时将
    添加到文本框

    我想添加 br 当用户单击输入按钮时 换行符 到文本框 我怎样才能在jquery中实现它onkeyup事件 可以给我展示一个示例或任何实现它的好网站吗 谢谢 从这里复制的文本区域中的插入符位置 从头开始的字符数 See DEMO
  • AJAX GET 请求中查询字符串的最大长度?

    执行 AJAX GET 请求时 查询字符串的最大长度是否存在 更具体地说 我正在使用图像进行跨域 AJAX img new Image img src http www otherdomain com something gif long
  • 获取提供给泛型方法的泛型参数类型和值

    如何获取提供给封闭 构造泛型方法的参数值 已经有一段时间没有接触Reflection了 所有这些都曾经是我的 嗯 无论如何 class Program static void Main string args new ConcreteFoo