C# .NET 反射 - 如何从 ParameterInfo 中获取“真实”类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/738277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET Reflection - How to get "real" type from out ParameterInfo
提问by randy909
I'm trying to validate that a parameter is both an out parameter and extends an interface (ICollection). The reflection api doesn't seem to want to give me the "real" type of the parameter, only the one with an "&" at the end which will not evaluate correctly in an IsAssignableFrom statement. I've written some c# code that works but it seems like there should be a better way to do this.
我正在尝试验证一个参数既是输出参数又是扩展接口 (ICollection)。反射 api 似乎不想给我参数的“真实”类型,只有在末尾带有“&”的参数不会在 IsAssignableFrom 语句中正确评估。我已经编写了一些有效的 c# 代码,但似乎应该有更好的方法来做到这一点。
bool isCachedArg(ParameterInfo pInfo)
{
if (!pInfo.IsOut)
return false;
string typeName = pInfo.ParameterType.FullName;
string nameNoAmpersand = typeName.Substring(0, typeName.Length - 1);
Type realType = Type.GetType(nameNoAmpersand);
if (!typeof(ICollection).IsAssignableFrom(realType))
return false;
return true;
}
Is there a way to get realType without reloading the Type from its string name? I'm still on .NET 2.1.
有没有办法在不从其字符串名称中重新加载 Type 的情况下获取 realType?我仍在使用 .NET 2.1。
Thanks, Randy
谢谢,兰迪
采纳答案by Jon Skeet
An out
parameter is "by ref" - so you'll find pInfo.ParameterType.IsByRef
returns true. To get the underlying not-by-ref type, call GetElementType()
:
一个out
参数是“by ref”——所以你会发现pInfo.ParameterType.IsByRef
返回true。要获取底层的非引用类型,请调用GetElementType()
:
Type realType = pInfo.ParameterType.GetElementType();
(You should only do that if it isby ref, of course. This applies for ref
parameters too.)
(您应该只有这样做,如果它是由参,当然,这适用于ref
参数了。)
回答by driis
Is pInfo.ParameterType not the type you are looking for ?
pInfo.ParameterType 不是您要查找的类型吗?
According to docs, the ParamterType property of the PropertyInfo class is: "The Type object that represents the Type of this parameter."
根据文档,PropertyInfo 类的 ParamterType 属性是: “表示此参数类型的 Type 对象。”
Also, the following code gives the expected output:
此外,以下代码给出了预期的输出:
Type t = typeof (X);
var mi = t.GetMethod("Method");
var parameters = mi.GetParameters();
foreach(Type parameterType in parameters.Select(pi => pi.ParameterType))
Console.WriteLine(parameterType.IsByRef ? parameterType.GetElementType() : parameterType);
Edit:As John Skeet points out, if the parameter is by ref; you should use GetElementType to get the correct type. I updated the code sample.
编辑:正如 John Skeet 指出的那样,如果参数是通过 ref; 您应该使用 GetElementType 来获取正确的类型。我更新了代码示例。
回答by Sarath Avanavu
You could also use
你也可以使用
Type type = Type.GetType("System."+ pInfo.ParameterType.Name);
if ParameterType.GetElementType()
doesn't work
如果ParameterType.GetElementType()
不起作用
回答by RSTavares
See this:
看到这个:
var parameters = methodinfo.GetParameters();
foreach (var parameter in parameters)
{
var HasValue = "";
Type ParameterType = (parameter.IsOut || parameter.ParameterType.IsByRef) ? parameter.ParameterType.GetElementType() : parameter.ParameterType;
if (ParameterType.GetProperties().Count() == 2 && ParameterType.GetProperties()[0].Name.Equals("HasValue"))
{
HasValue = "?";
ParameterType = ParameterType.GetProperties()[1].PropertyType;
}
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
var expr = new CodeTypeReferenceExpression(ParameterType);
var prov = new CSharpCodeProvider();
prov.GenerateCodeFromExpression(expr, sw, new CodeGeneratorOptions());
}
var result = string.Concat(sb.ToString(), HasValue, " ", parameter.Name);
Console.WriteLine(result);
}