反射小知识 【方法篇】
reflect_method
场景:
在方法定义时,我们有可能使用到 in/out/ref 这些关键字 来定义参数
in表示只读引用 -- 此特性出现在C# 7.2 由于此处使用的为C# 7.0 不进行测试说明
那么我们如何在反射中进行区分呢?
代码:
var type = typeof(Program);
var method = type.GetMethods();
foreach (var methodInfo in method)
{
Console.WriteLine($"{methodInfo.Name}>>>");
foreach (var parameterInfo in methodInfo.GetParameters())
{
var paramType = parameterInfo.ParameterType;//out 参数返回String& params 则是返回object[]
Console.WriteLine(paramType);
}
Console.WriteLine("---------------------------");
}
通过调试可知》
使用这些关键字定义参数时,反射获取的Type为System.String& 即 System.String ByRef
获取方法
在方法的定义时 你可能通过重载定义了如下两个方法:
public void Work(ref string confirm)//方法A
{
confirm = string.Empty;
}
public void Work(string confirm)//方法B
{
confirm = string.Empty;
}
常见的获取方法:
//创建方法参数所对应的Type数组
Type[] types = new Type[] { typeof(string)};
//通过参数列表对应的type和方法名 当然还有其他的筛选条件,例如:是否为public/static等等
var info = type.GetMethod("Work",types);
那么如何通过上述的这种方式来获取方法A?
解决方法:
Type[] types = new Type[] { typeof(string).MakeByRefType()};
通过MakeByRefType便可指定此参数为ref/out/in便能获取到方法A了,so easy 对吧
question 1
那如果获取了一个带有out/ref/in参数的方法,如何进行调用?
解决方法:
在调用时,传递object[]时不进行传值而是传递变量,调用后再使用变量继续后面的操作,就可以了
回顾
ref/out/in 常用于值类型的传入
因为值类型参数与引用类型的一起区别是
在方法内发现改变的时,变量值不发生改变
当然,引用类型,如果在方法内重新指定引用类型,方法调用后也不会发生改变的
根据vs 提示 在C# 7.2 引入的in 是用于只读参数的传递()
在此前的版本中由(Tuple<T1,T2...> readOnlyParam)来充当只读参数
ref 的作用则是用于保障方法调用时的修改会同步到方法调用后
out 与ref的作用类型类型,不过out作为参数时,此参数的值必须在方法中进行改变,且在方法内若使用了反射调用其他方法时,
也需要在改变此参数后进行传递
例如:
List<object> invokeParam = new List<object>();
invokeParam.Add(confirm);//error : 使用了未赋值的out 参数
扩展
在反射时 ref与out参数对应的type都是在原有类型上MakeByRefType后type 可见ref与out具有相似性
在ParameterInfo中 存在一个属性IsOut 通过调试可知
out 参数 >> true
ref 参数 >> false
out/in除了修饰参数外,还可以修饰泛型 》》 由于内容较多,请参考逆变与协变进行理解
author:monster
since:6/27/2018 5:41:26 PM
direction:反射小知识 【方法篇】