网站首页 > 技术文章 正文
反射是很多框架都用到的东西,是从0.25到0.5的一个进阶
反射可以动态创建对象,动态赋值,动态调用方法
反射可以在运行时获得类的信息
每个类都有一个 type对象,构造方法对应的是 ConstructorInfo对象,方法对应的是 MethodInfo对象,字段对应的是 FieldInfo对象,属性对应的是 PropertyInfo对象,使用时需要引用using System.Reflection;
Type
class Dog:Animal
{
public string name;
public int age;
double price;
static double weight;
public Dog() { }
public Dog(string name) { }
public Dog(string name,int age) { }
public override void Say() { }
public double Price { get; set; }
public double Weight { get; set; }
}
class Animal
{
public virtual void Say() { }
}
class Print
{
static void Main()
{
Dog dog = new Dog();
// 获取类的 type 对象常用的三种方式
Type type = typeof(Dog);
Type type1 = dog.GetType();
Type type2 = Type.GetType("Application.Dog");
//假设只知道类的名字,利用类名创建对象实例
Type t = typeof(Dog);
// Activator.CreateInstance(t); 被实例化的对象必须有无参构造方法,没有则会抛出 MissingMethodException 缺失方法异常
object dog1 = Activator.CreateInstance(t); // 相当于 new Dog();,由于返回的是 object ,所以只能用 object 接收
Console.WriteLine(dog1);
Console.WriteLine(t.BaseType); // 获取父类
Console.WriteLine(t.Name); // 获取类名
Console.WriteLine(t.FullName); // 获取全名,包含命名空间
Console.WriteLine(t.IsAbstract); // 判断是否为 抽象类
Console.WriteLine(t.IsArray); // 是否为 数组
Console.WriteLine(t.IsClass); // 是否为 普通类
Console.WriteLine(t.IsEnum); // 是否为 枚举
Console.WriteLine(t.IsPublic); // 是否为 public
Console.WriteLine(t.IsValueType); // 是否为 值类型
Console.WriteLine("------------* 构造方法 *---------------");
// 获取无参构造方法 t.GetConstructor(new Type[0]); 参数要求是 type对象数组,因此无参构造就只需要入参长度为 0 的数组就好了
ConstructorInfo c1 = t.GetConstructor(new Type[0]);
Console.WriteLine(c1); // Void .ctor ctor是IL里面构造方法的表现方式
// 获取参数类型为 string 的构造方法
c1 = t.GetConstructor(new Type[] { typeof(string) });
Console.WriteLine(c1);
// 获取参数类型为 string,int 的构造方法
c1 = t.GetConstructor(new Type[] { typeof(string), typeof(int) });
Console.WriteLine(c1);
Console.WriteLine("------------* 字段 *---------------");
// 获取所有字段,必须是public,获取的是未封装的字段
FieldInfo[] f1 = t.GetFields();
foreach (var field in f1)
{
Console.WriteLine(field);
}
// 获取 非public,且 非static 的字段,如果需要获取 static的,把Instance改成static
f1 = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var field in f1)
{
Console.WriteLine(field);
}
Console.WriteLine("------------* 方法 *---------------");
// 获得所有方法
MethodInfo[] m1 = t.GetMethods();
foreach (var method in m1)
{
Console.WriteLine(method);
}
// 获得指定方法
// 注:如果方法有重载,则抛出 AmbiguousMatchException
MethodInfo m2 = t.GetMethod("Say");
Console.WriteLine("\n"+m2);
// 解决方法抛出 AmbiguousMatchException异常
m2 = t.GetMethod("Say",new Type[0]); // 获取无参方法
m2 = t.GetMethod("Say",new Type[] { typeof(string)}); // 获取参数为 string 的方法
Console.WriteLine("------------* 属性 *---------------");
// 获得属性,获取到的是封装过的属性
PropertyInfo[] prop = t.GetProperties();
foreach (var p in prop)
{
Console.WriteLine(p);
}
}
}
输出:
Application.Dog
Application.Animal
Dog
Application.Dog
False
False
True
False
False
False
------------* 构造方法*---------------
Void.ctor()
Void .ctor(System.String)
Void .ctor(System.String, Int32)
------------* 字段*---------------
System.String name
System.Int32 age
System.Double price
System.Double<Price> k__BackingField
System.Double<Weight> k__BackingField
------------* 方法*---------------
Void Say()
Double get_Price()
Void set_Price(Double)
Double get_Weight()
Void set_Weight(Double)
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
System.String ToString()
Void Say()
------------* 属性*---------------
Double Price
Double Weight
反射示例 1
class Dog
{
public string name;
public void Say() { Console.WriteLine("你好,"+Name); }
public void Say(string name) { Console.WriteLine(#34;你好,{name}"); }
public string Name { get; set; }
}
class Print
{
// 反射示例
static void Main()
{
// 创建对象
Type t = typeof(Dog);
object obj = Activator.CreateInstance(t); // 创建对象,调用无参构造(方法1)
object obj1 = t.GetConstructor(new Type[0]).Invoke(new object[0]); // 获得对象的无参构造,调用(方法2)
// 给属性赋值
PropertyInfo prop = t.GetProperty("Name"); // 获得属性
prop.SetValue(obj, "大宝"); // 赋值
// 调用方法
MethodInfo method = t.GetMethod("Say", new Type[0]); // 获得无参方法
MethodInfo method1 = t.GetMethod("Say", new Type[] { typeof(string) }); // 获得有参方法
method.Invoke(obj, new object[0]); // 调用无参方法
method1.Invoke(obj, new object[] { "Tom" }); // 调用有参方法并赋值
}
}
输出:
你好,大宝
你好,Tom
反射示例 2
class Dog
{
public string name;
public void Say() { Console.WriteLine("你好,"+Name); }
public void Say(string name) { Console.WriteLine(#34;你好,{name}"); }
public string Name { get; set; }
}
class Print
{
static void Main()
{
Dog dog = new Dog();
dog.Name = "Tom";
Show(dog);
}
static void Show(object obj)
{
Type t = obj.GetType();
PropertyInfo[] prop = t.GetProperties();
foreach (var p in prop)
{
if (p.CanRead)
{
string name = p.Name;
object value = p.GetValue(obj);
Console.WriteLine(name+"="+value);
}
}
}
}
输出:
Name=Tom
反射示例3 (复制对象的值)(浅拷贝--仅复制对象的值,不是同一个对象)
class Dog
{
public string name;
public string Name { get; set; }
}
class Print
{
static void Main()
{
Dog dog = new Dog();
dog.Name = "Tom";
object dog1 = Clone(dog);
Console.WriteLine(object.ReferenceEquals(dog,dog1)); // 判断是否为同一个对象
}
static object Clone(object obj)
{
Type t = obj.GetType();
object newObject = Activator.CreateInstance(t); // 创建对象
PropertyInfo[] prop = t.GetProperties();
foreach (var p in prop)
{
if (p.CanRead&&p.CanWrite)
{
object value = p.GetValue(obj);
p.SetValue(newObject, value);
}
}
return newObject;
}
}
输出:
False
- 上一篇: C#自学——基础语法(看看就行)
- 下一篇: 2.6 C#的常用关键字和预定义类型
猜你喜欢
- 2025-01-16 C#13和 .NET9高级功能解析:.NET高手必备技能
- 2025-01-16 C#使用Autofac实现控制反转IoC和面向切面编程AOP
- 2025-01-16 C#设计模式(3)——工厂方法模式
- 2025-01-16 C# - 面向对象知识总结 082
- 2025-01-16 c#简单工厂、抽象工厂、反射
- 2025-01-16 C# 13 和 .NET 9 全知道 :9 处理文件、流和序列化 (1)
- 2025-01-16 Effective C++ 条款07 为多态基类声明virtual析构函数
- 2025-01-16 C# 数据结构和算法 :03 数组和排序(五)
- 2025-01-16 从零开始自学C#基础的最后一天——集合
- 2025-01-16 多态 C#
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)