你如何提供给封闭/构造泛型方法的参数值?
它已经有一段时间我都没有碰过反思。 这一切都曾经是在我,嗯,不管后面。
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实例感动particularizations和其他的MethodInfo为“模板” / open方法。
您可以使用它来获得你想要的东西:
class ConcreteFoo {
public void GenericMethod<Q>(Q q) {
var method = MethodInfo.GetCurrentMethod();
var closedMethod = method.MakeGenericMethod(typeof(Q));
// etc
}
}
这是为什么 ? 这是因为没有在反思“中列举行动”的返回是指封闭particularizations 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);
你会得到相同的结果。 至于GenericMethod和particularizations它的随从而言,你会得到只有GenericMethod(开放的变体)相关联的反射对象。
atTime2将不包含一个额外的MethodInfo参照新鲜即时编译GenericMethod <布尔>。
但是,这不是真的是一件坏事,现在是什么呢? 的getMethods()应该返回一致的结果,而不是有其效果随时间变化。 泛型方法的代数实际上是相当不错的,当涉及到它的“导航”操作:
- 所有开放MethodInfos已IsGenericMethod =真实IsGenericMethodDefinition =真
- 全封闭MethodInfos有IsGenericMethod =真,IsGenericMethodDefinition = FALSE
- 通过在一个封闭的MethodInfo调用.GetGenericMethodDefinition()你开一个
- 通过调用.MakeGenericType在一个开放的MethodInfo你得到你想要的任何闭一只(PARAMS键入[]类型)(而不语法知道什么这些类型是与接收异常不尊重的where子句的可能性)
这同样适用于这来自于当前线程的角度(而不是从该组件和类型)的反射操作:
MethodBase MethodInfo.GetCurrentMethod()
和
StackTrace trace = new StackTrace();
IEnumerable<MethodBase> methods = from frame in trace.GetFrames()
select frame.GetMethod();
有去无回的泛型方法(如果有的话),实际上是在上面,或在当前整个调用堆栈的实际关闭变种。
在某种程度上,你的问题是不是荒谬的,因为,而在GetCurrentMethod的情况下,你可以很容易地GetCurrentMethod加MakeGenericMethod加上语法可用的typeof(不管)替换它,你能不能说一下您的来电。
所以..非泛型方法,您可以随时看你的筹码,并精确地知道那些是什么方法参数类型。 该调用对方,并最终得到了你调用......但对于那些普通的(这是真的真的关闭,我再说一遍是不合逻辑的思考方法是运行并调用另一个,被别人称为通用的方法(等)是一个开放的),你不能找出类型的参数,就像你无法学习任何这样的方法的本地变量的值(这是确定的,但它会在性能有很大的缺陷,使一个可能性)。