反射小知识 【方法篇】

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:反射小知识 【方法篇】

posted @ 2018-06-28 12:05  前行丶  阅读(110)  评论(0编辑  收藏  举报