反射
运行时
操作某个类型的元数据
两种方法:
1.实例.getType()
2.typeof(类型)
3.注: 一个类型只有一个type
var a = new A();
var type1 = typeof(A); // typeof(类型)
var type2 = a.GetType(); // 实例.getType()
Console.WriteLine("他们的类型是一样的"+type1.Equals(type2));
我们看看Type里面有什么东西
我们现在开始使用吧!
class Program
{
class A { //通过反射调用方法
public string MyProperty { get; set; }
public void Func(int a) { Console.WriteLine(a); }
} //一个类型
static void Main(string[] args)
{
//反射 运行时操作某个类型的元数据
//两种实例方法
//注意: 一个类型只有一个type
//var type2 = a.GetType(); // 实例.getType()
//Console.WriteLine("他们的类型是一样的"+type1.Equals(type2));
var type = typeof(A); // typeof(类型)
var a = new A();
//GetProperty SetValue 使用方法
var property = type.GetProperty("MyProperty"); //我在property上拿到一个MyProperty属性,并且给他赋值aaa
property.SetValue(a,"aaa",null); //第一个 obj value index
//GetMethod Invoke 使用方法
var funcion = type.GetMethod("Func");
funcion.Invoke(a, new object[] { 1 });
Console.WriteLine(a.MyProperty);
}
用反射实现 用户输入A,则执行A,用户输入B,则执行B
class A { //通过反射调用方法
public string MyProperty { get; set; }
public void Func(int a) { Console.WriteLine(a); }
public void A1() { Console.WriteLine("in function A1"); }
public void B1() { Console.WriteLine("in function B1"); }
//用反射实现
//用户输入A,则执行A
//用户输入B,则执行B
string input= Console.ReadLine();
var funcion = type.GetMethod(input);
funcion.Invoke(a, null);
//switch (input) //旧方法
//{
// case "a":
// break;
// case "b":
// break;
//}
Console.WriteLine(a.MyProperty);
} //一个类型
根据字符串 创建类
Assembly
.Load("程序集名称")
.CreateInstance("命名空间.类名");
特性
展示一下程序集文件中的特性
用途
体用一个额外元数据
例子:比如设定属性为必填项
旧方法虽然可以放到很多类中检测,但是如果有很多类呢?很麻烦,这个方法已经一劳永逸了。
public class A
{ //通过反射调用方法
[Required]
public string MyProperty { get; set; }
public void Func(int a) { Console.WriteLine(a); }
//public bool Check() { //旧方法
// if (MyProperty == null) return false;return true;
//}
//public void A1() { Console.WriteLine("in function a.A1"); } //都有相同的方法
//public void B1() { Console.WriteLine("in function a.B1"); }
}
public class RequiredAttribute : System.Attribute {
public static bool IsPropertyRequired(object obj) {
var type = obj.GetType();
var properties = type.GetProperties();
foreach (var propetry in properties)
{
var attributes = propetry.GetCustomAttributes(typeof(RequiredAttribute),false);
if (attributes.Length>0)
{
if (propetry.GetValue(obj,null)==null)
return false;
}
}
return true;
}
}
var a = new A() { }; //MyProperty="123"未赋值
if (RequiredAttribute.IsPropertyRequired(a))
{
Console.WriteLine("已经赋值");
}
else
{
Console.WriteLine("未赋值");
}
序列化 反序列化
如何将一个实例 序列化为文件 然后反序列化
[Serializable] //可序列化
public class A
{
public string Test = "123";
}
//序列化
var a = new A();
using (var steam = File.Open(typeof(A).Name + "bin", FileMode.Create))
{
var bf = new BinaryFormatter();
bf.Serialize(steam, a);
}
//反序列化
A after = null;
using (var steam = File.Open(typeof(A).Name + "bin", FileMode.Open))
{
var bf = new BinaryFormatter();
after = (A)bf.Deserialize(steam);
}
Console.WriteLine(after.Test);
流
MSDN:stream是所有流的抽象基类,流是字节序列的抽象概念。例如文件,输入/输出设备 ,内部进程通信管道或者TCP/IP套接字。
我的理解:流是数据交换和传输的方式,方式上:文件流 网络流 内侧流,方向上 输入流 输出流。
流的继承体系
动态编程
仅介绍一个应用场景
解析XML文件
链接: 引用大佬的博客.
string xml = @"
<books>
<book></book>
<book><title>余华文城</title></book>
</books>
";
dynamic dyname = new DynamicXml(xml);
Console.WriteLine(dyname.book[1].title.Value);
引入一个类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace SerializeDemo
{
public class DynamicXml : DynamicObject, IEnumerable
{
private readonly List<XElement> _elements;
public DynamicXml(string text)
{
var doc = XDocument.Parse(text);
_elements = new List<XElement> { doc.Root };
}
protected DynamicXml(XElement element)
{
_elements = new List<XElement> { element };
}
protected DynamicXml(IEnumerable<XElement> elements)
{
_elements = new List<XElement>(elements);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
if (binder.Name == "Value")
result = _elements[0].Value;
else if (binder.Name == "Count")
result = _elements.Count;
else
{
var attr = _elements[0].Attribute(
XName.Get(binder.Name));
if (attr != null)
result = attr;
else
{
var items = _elements.Descendants(
XName.Get(binder.Name));
if (items == null || items.Count() == 0)
return false;
result = new DynamicXml(items);
}
}
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
int ndx = (int)indexes[0];
result = new DynamicXml(_elements[ndx]);
return true;
}
public IEnumerator GetEnumerator()
{
foreach (var element in _elements)
yield return new DynamicXml(element);
}
}
}
总结:反射很重要,动态加载类,特性的各种东西。