一、泛型
1.CLR编译时,编译器只为MyList<T>类型产生“泛型版”的IL代码——并不进行泛型的实例化,T在中间只充当占位符。例如:MyList 类型元数据中显示的<T>

2.执行的时候,当JIT编译器第一次遇到MyList<int>时,将用int替换“范型版”IL代码与元数据中的T—进行泛型类型的实例化。例如 :Main函数中显示的<int>

3.什么是泛型
泛型是具有占位符(类型参数)的类、方法、结构、接口

4.泛型类的继承
public class Father<K,V>{} //父类
(1)定义子类时直接为父类泛型参数赋值
public class Son : Father<int,string>
(2)定义子类时把子类泛型参数赋给父类泛型参数
public class Son<W,Y> : Father<W,Y>
(3)定义子类时有子类泛型参数,同时为父类泛型参数赋值
public class Son<W,Y> : Father<int,string>

5.泛型约束
(1)基类约束
private class House<T1, T2> where T1 : Dog where T2 : Cat
{

}
约束T1和T2必须继承Dog类和Cat类
(2)接口约束
class MyPetPlay<T, V> where T : IGetReward<T> where V : IWalk, ISing<V>
{

}
(3)结构和类约束
public class C<T> where T : struct
{
}
public class C2<T> where T : class
{
}
(4)构造函数约束
class Pet<T> where T : new()//T类中必须有无参数的构造函数
{
T t;
public Pet()
{
t = new T();
}
}

6.泛型方法
public int MethodName<T>(T param){...}
public int MethodName<T,K>(T param,K param2){...}
泛型方法 的泛型参数,可以用在该方法的 形参、方法体、返回值三处。

什么是元数据?
元数据(Metadata)描述了程序集的内容。通过将元数据嵌入每个程序集中,任何程序集都可以实现完全的自我描述,从而简化了发布使用较旧技术的组件时所需进行的工作。.NET使用元数据省略组件的注册过程。

程序集就是包含IL和元数据的集合,即从源代码编译生成的。

二、程序集和反射
1.程序集
我们所写的所有代码都会编译到程序集文件中,并在运行时以Assembly对象方式加载到内存中运行。
运行时,类会加载到内存中就是Type对象,类的成员(方法、字段、属性、事件等)加载到内存中也有相应的对象
2.反射
在程序运行时,动态获取加载程序集、动态获取类型(如类、接口等)、动态获取类型的成员信息(如方法、字段、属性等),动态创建类型实例,以及调用和访问这些实例成员。

Dog.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace WindowsForms20140808
{
public class Dog
{
public string name; public string Name
{
get { return name; }
set { name = value; }
}
public int Age { get; set; }
private bool gender; public string SayHi()
{
return this.Name + "," + this.Age + "," + this.gender;
}
}
}
 private void button1_Click(object sender, EventArgs e)
{
Dog d = new Dog();
d.Name = "旺旺";
d.Age = ;
d.SayHi();
//获取当前正在运行的程序集对象
Assembly ass = this.GetType().Assembly;
//获取程序集中的Dog类的类型对象
Type tDog = ass.GetType("WindowsForms20140808.Dog");
//也可以通过typeOf获取
//Type tDog = typeof (Dog); FieldInfo fInfo = tDog.GetField("name");
PropertyInfo pInfo = tDog.GetProperty("Name");
MethodInfo mInfo = tDog.GetMethod("SayHi");
//根据Dog的Type对象,实例化一个Dog对象
Dog d2 = Activator.CreateInstance<Dog>();
//使用Dog类的name字段对象,为d2实例的name字段赋值
fInfo.SetValue(d2, "小白"); //调用对象私有成员
FieldInfo fGender = tDog.GetField("gender", BindingFlags.NonPublic | BindingFlags.Instance);
fGender.SetValue(d2, true);
string strRes = mInfo.Invoke(d2, null).ToString(); //获得当前 程序域中 所有的Assembly
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
//获取当前正在运行的程序集对象
Assembly ass1 = this.GetType().Assembly;
//根据路径加载Assembly
Assembly ass2 = Assembly.LoadFrom("WindowsForms20140808.exe"); }

 三、利用反射和特性实现一个简单的记事本插件

1.实现记事本插件接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace TextNotePlugsInterface
{
/// <summary>
/// 记事本插件接口
/// </summary>
public interface IPlugs
{
/// <summary>
/// 处理文本
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
string ProcessText(string text);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace TextNotePlugsInterface
{
/// <summary>
/// 菜单特性类
/// </summary>
public class MenuNameAttribute : Attribute
{
private string _name; public string Name
{
get { return _name; }
set { _name = value; }
} public MenuNameAttribute(string name)
{
this._name = name;
}
}
}

2.实现具体的插件类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TextNotePlugsInterface; namespace TextNotePlugs
{
[MenuName("转换为小写")]
public class TextToLower:IPlugs
{
public string ProcessText(string text)
{
return text.ToLower();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TextNotePlugsInterface; namespace TextNotePlugs
{
[MenuName("转换为大写")]
public class TextToUpper:IPlugs
{
public string ProcessText(string text)
{
return text.ToUpper();
}
}
}

3.新建记事本程序,并将生成的记事本插件dll放入记事本程序的plugs文件夹中

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using TextNotePlugsInterface; namespace WindowsForms20140809
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
//通过反射获取插件的dll文件
string strPath = Path.GetDirectoryName(this.GetType().Assembly.Location) + "\\plugs";
string [] files =Directory.GetFiles(strPath,"*.dll");
foreach (string file in files)
{
Assembly ass = Assembly.LoadFrom(file);
//获取公开的类
Type[] types = ass.GetExportedTypes();
Type iplugsType = typeof (IPlugs);
foreach (Type type in types)
{
//判断type是否实现了IPlugs接口
if (iplugsType.IsAssignableFrom(type))
{
//获取类型的 MenuNameAttribute 特性对象,或将 内部的 Name属性值取出作为 按钮的文本
object[] attrs = type.GetCustomAttributes(typeof(MenuNameAttribute), false);
MenuNameAttribute menuAttr = attrs[] as MenuNameAttribute;
IPlugs iplug = Activator.CreateInstance(type) as IPlugs;
//创建插件按钮
ToolStripMenuItem menuItem = new ToolStripMenuItem(menuAttr.Name);
this.记事本插件ToolStripMenuItem.DropDownItems.Add(menuItem);
menuItem.Click += menuItem_Click;
menuItem.Tag = iplug;
}
}
} } void menuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
//从按钮中 取出 对应的 插件对象
IPlugs iplug = menuItem.Tag as IPlugs;
textBox1.Text = iplug.ProcessText(textBox1.Text);
} }
}

.net学习之泛型、程序集和反射的更多相关文章

  1. C# 篇基础知识9——特性、程序集和反射

    特性(Attribute)是用于为程序元素添加额外信息的一种机制.比如记录文件修改时间或代码作者.提示某方法已经过期.描述如何序列化数据等等.方法.变量.属性.类.接口.结构体以及程序集等都是程序元素 ...

  2. C#学习-程序集和反射

    准备项目 1.新建一个空的解决方案MyProj.sln 2.在该解决方案下,建一个控制台项目P01.csproj 3.在该项目下,自己新建一个类MyFirstClass.cs 查看解决方案MyProj ...

  3. 程序集和反射(C#)

    这里我又唠叨几句,大家在学习的时候,如看书或者看视频时觉得非常爽,因为感觉基本都看得懂也都挺容易的,其实看懂是一回事,你自己会动手做出来是一回事,自己能够说出来又是另一回事了.应该把学到的东西变成自己 ...

  4. C#编程之程序集和反射

    这里我又唠叨几句,大家在学习的时候,如看书或者看视频时觉得非常爽,因为感觉基本都看得懂也都挺容易的,其实看懂是一回事,你自己会动手做出来是一回事,自己能够说出来又是另一回事了.应该把学到的东西变成自己 ...

  5. c#基础语言编程-程序集和反射

    程序集 什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个 ...

  6. [译]聊聊C#中的泛型的使用(新手勿入) Seaching TreeVIew WPF 可编辑树Ztree的使用(包括对后台数据库的增删改查) 字段和属性的区别 C# 遍历Dictionary并修改其中的Value 学习笔记——异步 程序员常说的「哈希表」是个什么鬼?

    [译]聊聊C#中的泛型的使用(新手勿入)   写在前面 今天忙里偷闲在浏览外文的时候看到一篇讲C#中泛型的使用的文章,因此加上本人的理解以及四级没过的英语水平斗胆给大伙进行了翻译,当然在翻译的过程中发 ...

  7. JAVA学习笔记—review基本知识[反射与异常]

    JAVA学习笔记—review基本知识[反射与异常] 1.异常: 1.1异常的分类: Java会将所有的异常封装成对象,其根本父类为Throwable. Throwable有两个子类:Error 和E ...

  8. Java 理论和实践: 了解泛型 识别和避免学习使用泛型过程中的陷阱

    Brian Goetz (brian@quiotix.com), 首席顾问, Quiotix 简介: JDK 5.0 中增加的泛型类型,是 Java 语言中类型安全的一次重要改进.但是,对于初次使用泛 ...

  9. asp.net mvc本地程序集和GAC的程序集冲突解决方法

    一个从asp.net mvc 3升级到asp.net mvc 4的项目发生了如下错误: [A]System.Web.WebPages.Razor.Configuration.HostSection c ...

随机推荐

  1. Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法

    一. 分区表理论知识 Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中.分区完全对应用透明. Orac ...

  2. Java学习之强引用,弱引用,软引用 与 JVM

    1.java内存管理分为内存分配和内存回收,都不需要程序员负责. 2.垃圾回收的机制主要是看对象是否有引用指向该对象.  java对象的引用包括  强引用 软引用 弱引用 虚引用 3.强引用 是指创建 ...

  3. (转)android图片压缩总结

    原文地址:http://blog.csdn.net/cherry609195946/article/details/9264409 一.图片的存在形式 1.文件形式(即以二进制形式存在于硬盘上)2.流 ...

  4. Spring官网jar包下载方法

    Spring官网改版后,很多项目的完整zip包下载链接已经隐掉了,虽然Spring旨在引导大家用更“高大上”的maven方式来管理所依赖的jar包,但是完全没想到中国的国情,在伟大的墙内,直接通过ma ...

  5. fzu2172 字符串dp

    F - 巡了南山我巡北山 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  6. 转:sql之left join、right join、inner join的区别

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...

  7. MySQL知识点链接

    1.使用ab进行压力测试详解                                         http://www.365mini.com/page/apache-benchmark. ...

  8. 【leetcode】Populating Next Right Pointers in Each Node II

    Populating Next Right Pointers in Each Node II Follow up for problem "Populating Next Right Poi ...

  9. ios Swift 一些注意事项

    func test(one:NSString) -> NSString{ return "aaa" } func test(one:Int) -> NSString{ ...

  10. iOS coredata 级联删除

    应用场景如下,每个用户可以设定多个提醒,当删除一个用户时,应当把相关的提醒都删除,而删除一个提醒时,应当把提醒从用户信息中删除. 那么 Profile 应该建立一个如下图的relationship 而 ...