反思性地在C#中实现泛型类型推理 [英] Implementing Generic Type Inference in C# reflectively

查看:98
本文介绍了反思性地在C#中实现泛型类型推理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为脚本语言实现做一些泛型类型推断,我想知道是否缺少一些简单的方法。暂时让我问一下类型结构并忽略边界。举例来说,这是一个深度嵌套的例子:

  T foo (List   

现在我想测试是否可以传递参数栏类型:

 列表<列表<列表< string>>> 

添加到该方法中,然后使用发现的参数类型的MakeGenericMethod()来进行更改并调用它。

从我所知道的情况来看,即使我设法构建一个与foo参数等价的开放泛型类型(即 List< List< List< T>>> ),它将不会使用isAssignable()进行测试。我不确定是否有一些技巧来检查开放泛型类型的可分配性,还是仅仅不支持。我猜如果我不得不我可以直接做到这一点。



关于物化 - 它看起来像我将不得不递归爬行类型来找到参数类型匹配的类型参数的位置,然后做替换...我一直希望我能够以某种方式更直接地构造参数类型的可调用方法,但我没有看到如何做到这一点。

任何已经经历过这种疯狂的人的建议将不胜感激:)

谢谢,
Pat Niemeyer所以,我相信我已经成功地实现了这个假设,你必须确定可指定类型比较。就我所知,甚至没有办法从泛型类型中提取基类型以便自己执行赋值检查。所以我最终做的是使用GetGenericArguments并行地遍历方法参数类型和参数类型,在每个步骤执行完整性检查(通用参数匹配的次数等),并且一旦最终找到裸泛型类型参数,注意参数中的相应(推断)类型。您可以确定您使用IsGenericParameter找到了一个类型参数。然后,奇怪的是,您必须将这些类型保存在一边,并通过将它们按特定顺序传递给MakeGenericMethod来实例化该方法。该订单由Type自身的一个属性GenericParameterPosition(又是奇怪的)提供给您,但是一个简单的订单可以将它们排序。之后,所有正常规则似乎都适用。



--Pat


I need to do some generic type inference for a scripting language implementation and I am wondering if I am missing some straightforward approach. For the moment let me just ask about type structure and ignore bounds. To illustrate, here is a deeply nested example:

T foo<T>( List<List<List<T>>> ) {...}

Now I want to test if I can pass an argument bar of type:

List<List<List<string>>>

to that method and later use MakeGenericMethod() with the discovered param type to reify and invoke it.

From what I can tell, even if I manage to construct an open generic type equivalent to the foo argument (i.e. List<List<List<T>>>), it will not test with isAssignable(). I'm not sure if there is some trick to checking the assignability of open generic types or if it's simply not supported. I guess if I have to I can do this directly.

On the reification - It looks like I'm going to have to recursively crawl through the types to find the argument type that matches the location of the type parameter and then do the substitution... I had been hoping that I might be able to somehow construct the invocable method from the argument type more directly, but I'm not seeing how to do this.

Any advice from someone who's already gone through this madness would be appreciated :)

thanks, Pat Niemeyer

解决方案

So, I believe I have implemented this successfully going on the assumption that you have to reify the types for assignability comparison. As near as I can tell there is not even a way to extract the base type from a generic type in order to perform assignment checks yourself. So what I ended up doing is using GetGenericArguments to traverse the method parameter type and the argument type in parallel, performing sanity checks at each step (number of generic params match, etc.) and once ultimately finding the "naked" generic type param, noting the corresponding (inferred) type in the argument. You can determine that you've found a type param using IsGenericParameter. Then, weirdly, you have to save those types aside and use them to instantiate the method by passing them in a particular order to MakeGenericMethod. The order is provided for you by a property on Type itself, GenericParameterPosition, (again, weird) but a simple orderby sorts them out. After that all of the normal rules seem to apply.

-Pat

这篇关于反思性地在C#中实现泛型类型推理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆