一、泛型
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. jQuery lazyload插件详解和问题解答

    lazyload插件用于图片延迟加载,节省服务器带宽,减少服务器请求次数,提高网站的页面加载速度,用于网站性能优化,只有当图片在窗口可视范围内时才向服务器请求: 参数: threshold:设置距离窗 ...

  2. php5.3 appache phpstudy win7win8win10下 运行速度慢解决办法

         在部署服务器以及本地测试的时候发现了一个奇怪的现象,运行PHP程序的时候非常慢,起先以为是网速的原因,后经本地测试发现速度依旧非常慢,打开一个页面差不多要用时3秒以上,这肯定是不正常的,因为 ...

  3. NUI控件扩展

    摘要:NUI组件是公司新一代的前端开发框架,它精致优雅的前端编程模型,是大家能够,或者想接受学习它的重要原因,在使用它的时候,一定不免会想增加自己的控件,让别人也能够如此优雅的使用. 其实NUI的扩展 ...

  4. Largest BST Subtree

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  5. 【leetcode】Integer to Roman

    Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...

  6. 如何使用shell脚本快速排序和去重文件数据

    前面写过一篇通过shell脚本去重10G数据的文章,见<用几条shell命令快速去重10G数据>.然而今天又碰到另外一个业务,业务复杂度比上次的单纯去重要复杂很多.找了很久没有找到相应的办 ...

  7. iOS NSObject 的 isa 属性的类型 Class

    以前对NSObject的isa属性也知道点,但是了解不深,今天看了这篇博文,感觉很好,总结一下: http://chun.tips/blog/2014/11/05/bao-gen-wen-di-obj ...

  8. ACM/ICPC 之 BFS-简单障碍迷宫问题(POJ2935)

    题目确实简单,思路很容易出来,难点在于障碍的记录,是BFS迷宫问题中很经典的题目了. POJ2935-Basic Wall Maze 题意:6*6棋盘,有三堵墙,求从给定初始点到给定终点的最短路,输出 ...

  9. InnoDB O_DIRECT选项漫谈(一)【转】

    本文来自:http://insidemysql.blog.163.com/blog/static/2028340422013671186977/   最近和文件系统内核开发人员做技术交流,对O_DIR ...

  10. Java Thread.join()方法

    一.使用方式. join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二.为什么要用join() ...