zoukankan      html  css  js  c++  java
  • 反射小知识 【方法篇】

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

  • 相关阅读:
    WPF之感触
    C# WinForm 给DataTable中指定位置添加列
    MyEclipse 8.6 download 官方下载地址
    将博客搬至CSDN
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
  • 原文地址:https://www.cnblogs.com/monster17/p/9238068.html
Copyright © 2011-2022 走看看