c#的泛型,委托,反射是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#的泛型,委托,反射是啥?相关的知识,希望对你有一定的参考价值。

c#的泛型,委托,反射是什么,请高手简单说明一下并举个简单扼要的例子?要代码,谢谢回答!

委托:将方法作为方法的参数
我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语:

public void GreetPeople(string name)
// 做某些额外的事情,比如初始化之类,此处略
EnglishGreeting(name);

public void EnglishGreeting(string name)
Console.WriteLine("Morning, " + name);


暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出 “Morning, Jimmy”。

现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法:

public void ChineseGreeting(string name)
Console.WriteLine("早上好, " + name);


这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据:

public enum Language
English, Chinese


public void GreetPeople(string name, Language lang)
//做某些额外的事情,比如初始化之类,此处略
swith(lang)
case Language.English:
EnglishGreeting(name);
break;
case Language.Chinese:
ChineseGreeting(name);
break;



OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。

在考虑新的解决方案之前,我们先看看 GreetPeople的方法签名:

public void GreetPeople(string name, Language lang)

仅看 string name,在这里,string 是参数类型,name 是参数变量,当我们赋给name字符串“jimmy”时,它就代表“jimmy”这个值;当我们赋给它“刘XX”时,它又代表着“刘XX”这个值。然后,我们可以在方法体内对这个name进行其他操作。哎,这简直是废话么,刚学程序就知道了。

如果你再仔细想想,假如GreetPeople()方法可以接受一个参数变量,这个变量可以代表另一个方法,当我们给这个变量赋值 EnglishGreeting的时候,它代表着 EnglsihGreeting() 这个方法;当我们给它赋值ChineseGreeting 的时候,它又代表着ChineseGreeting()方法。我们将这个参数变量命名为 MakeGreeting,那么不是可以如同给name赋值时一样,在调用 GreetPeople()方法的时候,给这个MakeGreeting 参数也赋上值么(ChineseGreeting或者EnglsihGreeting等)?然后,我们在方法体内,也可以像使用别的参数一样使用MakeGreeting。但是,由于MakeGreeting代表着一个方法,它的使用方式应该和它被赋的方法(比如ChineseGreeting)是一样的,比如:

MakeGreeting(name);

好了,有了思路了,我们现在就来改改GreetPeople()方法,那么它应该是这个样子了:

public void GreetPeople(string name, *** MakeGreeting)
MakeGreeting(name);


注意到 *** ,这个位置通常放置的应该是参数的类型,但到目前为止,我们仅仅是想到应该有个可以代表方法的参数,并按这个思路去改写GreetPeople方法,现在就出现了一个大问题:这个代表着方法的MakeGreeting参数应该是什么类型的?

NOTE:这里已不再需要枚举了,因为在给MakeGreeting赋值的时候动态地决定使用哪个方法,是ChineseGreeting还是 EnglishGreeting,而在这个两个方法内部,已经对使用“morning”还是“早上好”作了区分。

聪明的你应该已经想到了,现在是委托该出场的时候了,但讲述委托之前,我们再看看MakeGreeting参数所能代表的 ChineseGreeting()和EnglishGreeting()方法的签名:

public void EnglishGreeting(string name)
public void ChineseGreeting(string name)

如同name可以接受String类型的“true”和“1”,但不能接受bool类型的true和int类型的1一样。MakeGreeting的 参数类型定义 应该能够确定 MakeGreeting可以代表的方法种类,再进一步讲,就是MakeGreeting可以代表的方法 的 参数类型和返回类型。

于是,委托出现了:它定义了MakeGreeting参数所能代表的方法的种类,也就是MakeGreeting参数的类型。

NOTE:如果上面这句话比较绕口,我把它翻译成这样:string 定义了name参数所能代表的值的种类,也就是name参数的类型。

本例中委托的定义:

public delegate void GreetingDelegate(string name);

可以与上面EnglishGreeting()方法的签名对比一下,除了加入了delegate关键字以外,其余的是不是完全一样?

现在,让我们再次改动GreetPeople()方法,如下所示:

public void GreetPeople(string name, GreetingDelegate MakeGreeting)
MakeGreeting(name);


如你所见,委托GreetingDelegate出现的位置与 string相同,string是一个类型,那么GreetingDelegate应该也是一个类型,或者叫类(Class)。但是委托的声明方式和类却完全不同,这是怎么一回事?实际上,委托在编译的时候确实会编译成类。因为Delegate是一个类,所以在任何可以声明类的地方都可以声明委托。更多的内容将在下面讲述,现在,请看看这个范例的完整代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate
//定义委托,它定义了可以代表的方法的类型
public delegate void GreetingDelegate(string name);
class Program

private static void EnglishGreeting(string name)
Console.WriteLine("Morning, " + name);


private static void ChineseGreeting(string name)
Console.WriteLine("早上好, " + name);


//注意此方法,它接受一个GreetingDelegate类型的方法作为参数
private static void GreetPeople(string name, GreetingDelegate MakeGreeting)
MakeGreeting(name);


static void Main(string[] args)
GreetPeople("Jimmy Zhang", EnglishGreeting);
GreetPeople("XXX", ChineseGreeting);
Console.ReadKey();




输出如下:
Morning, Jimmy Zhang
早上好, XXX

现在对委托做一个总结:

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
参考技术A 我学这些东西的时候在网络上查了很久,感觉都很专业,初学者难以理解什么时候用,也很难找到简单的介绍,稍微整理一下下:
------------------------------------------------------------------------------------------------------------------------------------------------------------
反射 : Reflection
1. 基类调用派生类时候用
2. 在运行时才确定要调用哪个类的时候用
3. 在运行期 获取 模块 程序集 类 构造函数 属性方法的信息 以及实例化类,
调用构造函数,属性,方法,事件,委托等……通过对类型动态实例化后,还可以用反射对其执行操作
4. 如果在写代码的时候就能确定要调用的是哪个类,那直接调用当然好了。
但很多场合(也许是为了通用性),要在运行期才能够决定需要调用的类型,那样就有必要用反射来取得类型的相关信息了

简单来说就是用string可以在runtime为所欲为的东西,实际上就是一个.net framework内建的万能工厂
------------------------------------------------------------------------------------------------------------------------------------------------------------
泛型 :
1. 减少装箱拆箱,性能高 2. 类型安全 3. 工作效率提高
可是谁知道怎么简单的描述他?
减少装箱拆箱的技术,什么是装箱,从物理上说是:
把堆栈上的对象复制到堆上
也可以说将值类型(全部继承自system.ValueType)转换为引用类型,反之叫拆箱
那什么是值类型,引用类型?
整数类型,浮点类型,布尔类型,枚举类型,结构体类型,字符类型叫值类型
字符串类型,OBJECT类型,类类型,数组类型,委托类型,接口类型叫引用类型
什么是堆栈,什么是堆?
正在研究中…………

------------------------------------------------------------------------------------------------------------------------------------------------------------
缓存 - 缓存依赖 :
1. 当用户再次访问这个网页的时候,被格式化好的html会被直接送显。 速度快,直接存在内存中
2. 依赖于数据源,数据源发生更改时重新生成缓存,数据源可以是文件,数据库等
一般来说优化网站时候用
--------------------------------------------------------------------------------------------------------------------------------------------------------------
委托 :
1. 委托是可以申明的类型,方法看做委托的实例 ,所以说方法可以传递滴!
(将方法作为参数传递),可以避免在程序中大量使用If-Else(Switch)等语句,同时使得程序具有更好的可扩展性。
2. 使用委托可以将多个方法绑定到同一个委托的变量上( += 或 -=)
3. 一个事件不管是不是声明为public,但是它实际上都是private,私有变量是不可以直接用等号(=)的,也就是说事件用=号来绑定一个函数是不好滴
所有一般用封装了的 += , -= 实际上 += ”对应 add_XXX()方法, “-=”对应 remove_XXX()方法。
4. 返回值都为void
如果定义了返回值,那么多个订阅 者的方法都会向发布者返回数值,结果就是后面一个返回的方法值将前面的返回值覆盖掉了,
因此,实际上只能获得最后一个方法调用的返回值。
5.委托相当于C中的指针,它是类型安全的
委托相当于老板,老板可以随意支配许多员工做事,也可以解雇员工,一个委托也可以绑定N多函数,也可以取消一些绑定

有不好的请指正哟!本回答被提问者采纳
参考技术B 浅谈C#泛型的用处http://www.fcbcw.com/content.aspx?id=478443351346
学习C#委托 http://www.fcbcw.com/content.aspx?id=855186604252
反射 动态加载dll 返回一个对象

祝好运
参考技术C

我的建议,初学者并不一定要把所有问题都理解。

你只管去学你能理解的东西。

如果你基础不到,别人讲得再好,你也理解不了。

理解不了的先不去管。

这是我对初学者的建议。

   --洛阳知道

记录C#泛型

常见的泛型类型

泛型类
class MyClass<T>
{
    //......
}

泛型接口
interface  GenericInterface<T>
{
    void  GenericMethod(T t);
}

泛型方法
public void MyGenericMethod<T>()
{
     //......
}

泛型数组
public T[] GenericArray;

泛型委托
public delegate TOutput GenericDelagete<TInput, TOutput>(TInput input);

泛型结构
struct MyGenericStruct<T>
{

}

泛型约束

  约束   说明
  T:结构   类型参数必须是值类型
  T:类   类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
  T:new()   类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。
  T:<基类名>   类型参数必须是指定的基类或派生自指定的基类。
  T:<接口名称>   类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。

 1、基类约束

 1 /// <summary>
 2 /// 基类约束:约束T必须是People类型或者是People的子类
 3 /// </summary>
 4 /// <typeparam name="T"></typeparam>
 5 /// <param name="tParameter"></param>
 6 public static void Show<T>(T tParameter) where T : People
 7 {
 8     Console.WriteLine($"{tParameter.Id}_{tParameter.Name}");
 9     Parameter.Hi();
10 }

注意:

基类约束时,基类不能是密封类,即不能是sealed类。sealed类表示该类不能被继承,在这里用作约束就无任何意义,因为sealed类没有子类。

2、接口约束

技术图片
/// <summary>
/// 接口约束
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public static T Get<T>(T t) where T : ISports
{
    t.Pingpang();
    return t;
}
技术图片

 3、引用类型约束 class

引用类型约束保证T一定是引用类型的。

技术图片
 1 /// <summary>
 2 /// 引用类型约束
 3 /// </summary>
 4 /// <typeparam name="T"></typeparam>
 5 /// <param name="t"></param>
 6 /// <returns></returns>
 7 public static T Get<T>(T t) where T : class
 8 {
 9     return t;
10 }
技术图片

 4、值类型约束  struct

值类型约束保证T一定是值类型的。

技术图片
 1 /// <summary>
 2 /// 值类型类型约束
 3 /// </summary>
 4 /// <typeparam name="T"></typeparam>
 5 /// <param name="t"></param>
 6 /// <returns></returns>
 7 public static T Get<T>(T t) where T : struct
 8 {
 9     return t;
10 }
技术图片

 5、无参数构造函数约束  new()

技术图片
 1 /// <summary>
 2 /// new()约束
 3 /// </summary>
 4 /// <typeparam name="T"></typeparam>
 5 /// <param name="t"></param>
 6 /// <returns></returns>
 7 public static T Get<T>(T t) where T : new()
 8 {
 9     return t;
10 }
技术图片

 泛型约束也可以同时约束多个,例如:

技术图片
1 public static void Show<T>(T tParameter)
2             where T : People, ISports, IWork, new()
3 {
4     Console.WriteLine($"{tParameter.Id}_{tParameter.Name}");
5     tParameter.Hi();
6     tParameter.Pingpang();
7     tParameter.Work();
8 }
技术图片

 注意:有多个泛型约束时,new()约束一定是在最后。

转载:https://www.cnblogs.com/dotnet261010/p/9034594.html

转载:https://blog.csdn.net/kebi007/article/details/77800954

以上是关于c#的泛型,委托,反射是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java的泛型反射

java的泛型与反射机制

Java之反射机制六:获取方法的泛型信息

c#中的泛型委托(@WhiteTaken)

C#中的泛型是啥意思?

java 反射和泛型-反射来获取泛型信息