gpt4 book ai didi

C#反射

转载 作者:我是一只小鸟 更新时间:2023-05-01 22:31:32 35 4
gpt4 key购买 nike

C#反射简介

反射(Reflection)是C#语言中一种非常有用的机制,它可以在运行时动态获取对象的类型信息并且进行相应的操作。 反射是一种在.NET  Framework中广泛使用的技术,它是实现上述特性的基础,非常重要.

反射能干什么?

使用反射可以让我们在运行时动态地获取对象的类型信息并进行相应的操作,比如创建对象、调用方法、获取属性等。举个简单的例子,我们在写代码时,为了能够调用某个对象的方法,我们通常需要先创建这个对象的实例,然后才能调用其方法。而使用反射机制,我们可以在运行时动态地创建对象并直接调用其方法,而不必提前定义它们.

反射的基本使用

反射的核心是Type类, 它表示.NET  Framework中的类型,即类、结构体、枚举等。我们可以使用Type类来获取程序集中定义的类型,获取类型的成员,创建类型的实例等等。下面我们举几个反射的基本使用案例.

1. 获取类型信息

获取类型信息是反射最基本的用法之一,我们可以使用Type类的静态方法GetType获取类型信息,如下所示.

                                
                                  using
                                
                                
                                   System;

                                
                                
                                  namespace
                                
                                
                                   ReflectionDemo
{
    
                                
                                
                                  class
                                
                                
                                   Program
    {
        
                                
                                
                                  static
                                
                                
                                  void
                                
                                 Main(
                                
                                  string
                                
                                
                                  [] args)
        {
            Type type 
                                
                                = 
                                
                                  typeof
                                
                                (
                                
                                  string
                                
                                
                                  );
            Console.WriteLine(type.FullName);
            Console.ReadKey();
        }
    }
}
                                
                              

这个例子中,我们获取了string类型的Type对象,然后输出了这个对象的FullName属性,也就是string类型的完全限定名称System.String.

2. 反射创建对象

使用反射可以在运行时动态地创建对象,这极大地方便了我们的编程工作。例如,我们通常要编写一个工厂类来根据不同的类型创建不同的对象,而使用反射则可以在不需要工厂类的情况下创建对象。下面是一个简单的例子.

                                  
                                    using
                                  
                                  
                                     System;

                                  
                                  
                                    using
                                  
                                  
                                     System.Reflection;


                                  
                                  
                                    namespace
                                  
                                  
                                     ReflectionDemo
{
    
                                  
                                  
                                    class
                                  
                                  
                                     MyClass
    {
        
                                  
                                  
                                    public
                                  
                                  
                                    int
                                  
                                   Id { 
                                  
                                    get
                                  
                                  ; 
                                  
                                    set
                                  
                                  
                                    ; }
        
                                  
                                  
                                    public
                                  
                                  
                                    string
                                  
                                   Name { 
                                  
                                    get
                                  
                                  ; 
                                  
                                    set
                                  
                                  
                                    ; }
    }

    
                                  
                                  
                                    class
                                  
                                  
                                     Program
    {
        
                                  
                                  
                                    static
                                  
                                  
                                    void
                                  
                                   Main(
                                  
                                    string
                                  
                                  
                                    [] args)
        {
            
                                  
                                  
                                    //
                                  
                                  
                                     获取 MyClass 的类型对象
                                  
                                  
            Type myClassType = 
                                  
                                    typeof
                                  
                                  
                                    (MyClass);

            
                                  
                                  
                                    //
                                  
                                  
                                     创建 MyClass 类型的实例
                                  
                                  
            MyClass myClass =
                                  
                                     (MyClass)Activator.CreateInstance(myClassType);

            
                                  
                                  
                                    //
                                  
                                  
                                     设置对象属性值
                                  
                                  
            PropertyInfo propId = myClassType.GetProperty(
                                  
                                    "
                                  
                                  
                                    Id
                                  
                                  
                                    "
                                  
                                  
                                    );
            propId.SetValue(myClass, 
                                  
                                  
                                    100
                                  
                                  
                                    );

            PropertyInfo propName 
                                  
                                  = myClassType.GetProperty(
                                  
                                    "
                                  
                                  
                                    Name
                                  
                                  
                                    "
                                  
                                  
                                    );
            propName.SetValue(myClass, 
                                  
                                  
                                    "
                                  
                                  
                                    Tom
                                  
                                  
                                    "
                                  
                                  
                                    );

            
                                  
                                  
                                    //
                                  
                                  
                                     打印对象属性值
                                  
                                  
                                                Console.WriteLine(myClass.Id);
            Console.WriteLine(myClass.Name);

            Console.ReadLine();
        }
    }
}
                                  
                                

上述代码中,我们首先获取了  MyClass  类型的对象,然后调用  Activator.CreateInstance  方法来创建该类型的实例。接着,我们利用  PropertyInfo  对象获取、设置对象的属性值,最后打印属性值。以上就是用反射机制在 C# 中创建对象的过程.

3. 反射调用方法

使用反射可以在运行时动态地调用对象的方法。我们可以使用MethodInfo类来获取方法信息,然后调用MethodInfo.Invoke方法来调用这个方法,如下所示.

                                        
                                          using
                                        
                                        
                                           System;

                                        
                                        
                                          using
                                        
                                        
                                           System.Reflection;

                                        
                                        
                                          namespace
                                        
                                        
                                           ReflectionDemo
{
    
                                        
                                        
                                          class
                                        
                                        
                                           Program
    {
        
                                        
                                        
                                          static
                                        
                                        
                                          void
                                        
                                         Main(
                                        
                                          string
                                        
                                        
                                          [] args)
        {
            Type type 
                                        
                                        = 
                                        
                                          typeof
                                        
                                        (
                                        
                                          string
                                        
                                        
                                          );
            MethodInfo method 
                                        
                                        = type.GetMethod(
                                        
                                          "
                                        
                                        
                                          ToUpper
                                        
                                        
                                          "
                                        
                                        , 
                                        
                                          new
                                        
                                        
                                           Type[] { });
            
                                        
                                        
                                          string
                                        
                                         result = (
                                        
                                          string
                                        
                                        )method.Invoke(
                                        
                                          "
                                        
                                        
                                          Hello World
                                        
                                        
                                          "
                                        
                                        , 
                                        
                                          null
                                        
                                        
                                          );
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }
                                          
}

这个例子中,我们获取了string类型的ToUpper方法信息,然后使用Invoke方法调用这个方法,将字符串"Hello World"转化为大写输出.

反射的高级用法

反射的高级用法是指使用反射来实现更高级的编程功能,比如泛型、LINQ等。下面我们举几个例子展示反射的高级用法.

1. 获取泛型方法信息

使用反射可以在运行时动态地获取泛型方法的信息,然后在运行时构造泛型类型。下面是一个例子.

 
                                                  
                                                    using
                                                  
                                                  
                                                     System;

                                                  
                                                  
                                                    using
                                                  
                                                  
                                                     System.Reflection;

                                                  
                                                  
                                                    namespace
                                                  
                                                  
                                                     ReflectionDemo
{
    
                                                  
                                                  
                                                    class
                                                  
                                                  
                                                     Program
    {
        
                                                  
                                                  
                                                    static
                                                  
                                                  
                                                    void
                                                  
                                                   Main(
                                                  
                                                    string
                                                  
                                                  
                                                    [] args)
        {
            Type type 
                                                  
                                                  = 
                                                  
                                                    typeof
                                                  
                                                  
                                                    (Program);
            MethodInfo method 
                                                  
                                                  = type.GetMethod(
                                                  
                                                    "
                                                  
                                                  
                                                    TestMethod
                                                  
                                                  
                                                    "
                                                  
                                                  
                                                    );
            MethodInfo genericMethod 
                                                  
                                                  = method.MakeGenericMethod(
                                                  
                                                    typeof
                                                  
                                                  (
                                                  
                                                    string
                                                  
                                                  
                                                    ));
            genericMethod.Invoke(
                                                  
                                                  
                                                    null
                                                  
                                                  , 
                                                  
                                                    null
                                                  
                                                  
                                                    );
            Console.ReadKey();
        }
        
                                                  
                                                  
                                                    public
                                                  
                                                  
                                                    static
                                                  
                                                  
                                                    void
                                                  
                                                   TestMethod<T>
                                                  
                                                    ()
        {
            Console.WriteLine(
                                                  
                                                  
                                                    typeof
                                                  
                                                  
                                                    (T).FullName);
        }
    }
}
                                                  
                                                

这个例子中,我们使用GetMethod方法获取了TestMethod方法信息,然后使用MakeGenericMethod方法构造了泛型方法,并将其转化为MethodInfo类进行输出.

2. 在运行时构造LINQ查询

使用反射可以在运行时动态地根据查询条件构造LINQ查询。下面是一个例子.

 
                                                        
                                                          using
                                                        
                                                        
                                                           System;

                                                        
                                                        
                                                          using
                                                        
                                                        
                                                           System.Collections.Generic;

                                                        
                                                        
                                                          using
                                                        
                                                        
                                                           System.Linq;

                                                        
                                                        
                                                          using
                                                        
                                                        
                                                           System.Linq.Expressions;

                                                        
                                                        
                                                          using
                                                        
                                                        
                                                           System.Reflection;


                                                        
                                                        
                                                          namespace
                                                        
                                                        
                                                           ReflectionDemo
{
    
                                                        
                                                        
                                                          class
                                                        
                                                        
                                                           MyEntity
    {
        
                                                        
                                                        
                                                          public
                                                        
                                                        
                                                          int
                                                        
                                                         Id { 
                                                        
                                                          get
                                                        
                                                        ; 
                                                        
                                                          set
                                                        
                                                        
                                                          ; }
        
                                                        
                                                        
                                                          public
                                                        
                                                        
                                                          string
                                                        
                                                         Name { 
                                                        
                                                          get
                                                        
                                                        ; 
                                                        
                                                          set
                                                        
                                                        
                                                          ; }
    }

    
                                                        
                                                        
                                                          class
                                                        
                                                        
                                                           Program
    {
        
                                                        
                                                        
                                                          static
                                                        
                                                        
                                                          void
                                                        
                                                         Main(
                                                        
                                                          string
                                                        
                                                        
                                                          [] args)
        {
            
                                                        
                                                        
                                                          //
                                                        
                                                        
                                                           构造查询条件
                                                        
                                                        
                                                          string
                                                        
                                                         fieldName = 
                                                        
                                                          "
                                                        
                                                        
                                                          Id
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                          ;
            
                                                        
                                                        
                                                          int
                                                        
                                                         fieldValue = 
                                                        
                                                          100
                                                        
                                                        
                                                          ;

            
                                                        
                                                        
                                                          //
                                                        
                                                        
                                                           获取运行时类型和字段信息
                                                        
                                                        
            Type entityType = 
                                                        
                                                          typeof
                                                        
                                                        
                                                          (MyEntity);
            PropertyInfo property 
                                                        
                                                        =
                                                        
                                                           entityType.GetProperty(fieldName);

            
                                                        
                                                        
                                                          //
                                                        
                                                        
                                                           使用表达式树构造查询条件
                                                        
                                                        
            ParameterExpression parameter = Expression.Parameter(entityType, 
                                                        
                                                          "
                                                        
                                                        
                                                          x
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                          );
            MemberExpression member 
                                                        
                                                        =
                                                        
                                                           Expression.Property(parameter, property);
            ConstantExpression constant 
                                                        
                                                        =
                                                        
                                                           Expression.Constant(fieldValue, property.PropertyType);
            BinaryExpression equal 
                                                        
                                                        =
                                                        
                                                           Expression.Equal(member, constant);
            Expression
                                                        
                                                        <Func<MyEntity, 
                                                        
                                                          bool
                                                        
                                                        >> expression = Expression.Lambda<Func<MyEntity, 
                                                        
                                                          bool
                                                        
                                                        >>
                                                        
                                                          (equal, parameter);

            
                                                        
                                                        
                                                          //
                                                        
                                                        
                                                           执行查询
                                                        
                                                        
            IQueryable<MyEntity> entities = 
                                                        
                                                          new
                                                        
                                                         List<MyEntity>
                                                        
                                                          
            {
                
                                                        
                                                        
                                                          new
                                                        
                                                         MyEntity { Id = 
                                                        
                                                          100
                                                        
                                                        , Name = 
                                                        
                                                          "
                                                        
                                                        
                                                          Alice
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                           },
                
                                                        
                                                        
                                                          new
                                                        
                                                         MyEntity { Id = 
                                                        
                                                          200
                                                        
                                                        , Name = 
                                                        
                                                          "
                                                        
                                                        
                                                          Bob
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                           },
                
                                                        
                                                        
                                                          new
                                                        
                                                         MyEntity { Id = 
                                                        
                                                          300
                                                        
                                                        , Name = 
                                                        
                                                          "
                                                        
                                                        
                                                          Charlie
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                           },
                
                                                        
                                                        
                                                          new
                                                        
                                                         MyEntity { Id = 
                                                        
                                                          400
                                                        
                                                        , Name = 
                                                        
                                                          "
                                                        
                                                        
                                                          David
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                           },
            }.AsQueryable();
            IQueryable
                                                        
                                                        <MyEntity> query =
                                                        
                                                           entities.Where(expression);

            
                                                        
                                                        
                                                          //
                                                        
                                                        
                                                           输出查询结果
                                                        
                                                        
                                                          foreach
                                                        
                                                         (MyEntity entity 
                                                        
                                                          in
                                                        
                                                        
                                                           query)
            {
                Console.WriteLine($
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                          Id={entity.Id}, Name={entity.Name}
                                                        
                                                        
                                                          "
                                                        
                                                        
                                                          );
            }

            Console.ReadLine();
        }

        
                                                        
                                                        
                                                          static
                                                        
                                                        
                                                          object
                                                        
                                                        
                                                           CreateWhereLambda(Type elementType)
        {
            MethodInfo whereMethod 
                                                        
                                                        = 
                                                        
                                                          typeof
                                                        
                                                        (Program).GetMethod(nameof(CreateWhereLambdaImpl), BindingFlags.NonPublic |
                                                        
                                                           BindingFlags.Static);
            
                                                        
                                                        
                                                          return
                                                        
                                                         whereMethod.MakeGenericMethod(elementType).Invoke(
                                                        
                                                          null
                                                        
                                                        , 
                                                        
                                                          null
                                                        
                                                        
                                                          );
        }

        
                                                        
                                                        
                                                          static
                                                        
                                                         Func<T, 
                                                        
                                                          bool
                                                        
                                                        > CreateWhereLambdaImpl<T>
                                                        
                                                          ()
        {
            
                                                        
                                                        
                                                          return
                                                        
                                                         item => (
                                                        
                                                          int
                                                        
                                                        )(
                                                        
                                                          object
                                                        
                                                        )item % 
                                                        
                                                          2
                                                        
                                                         == 
                                                        
                                                          0
                                                        
                                                        
                                                          ;
        }
    }
}
                                                        
                                                      

在上述示例中,我们首先定义了一个查询条件,然后获取了运行时类型和字段信息,接着使用表达式树构造了查询条件,并利用反射执行了 LINQ 查询。最终,我们输出的结果只包括  Id  等于 100 的实体.

反射使用的注意事项

使用反射需要格外注意性能和安全问题,一些常见的注意事项包括:

  1. 尽量使用已经编译好的程序集,避免使用动态编译的程序集。
  2. 反射的性能较低,尽量少用。
  3. 反射有漏洞,应注意安全问题。
  4. 授权可以防止反射的滥用,应根据实际情况授权反射使用权限。

总结

通过本文的学习,我们了解了反射的基本概念和使用方法,并且掌握了反射的高级用法。反射在C#中是一项非常强大且必要的技术,如果恰当地使用它,可以使我们的编程工作变得更加高效和便捷。同时,我们也需要格外注意反射使用过程中的性能和安全问题,做好样本授权等工作,以便更好地使用反射这个强大的功能.

 

最后此篇关于C#反射的文章就讲到这里了,如果你想了解更多关于C#反射的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com