泛型 System.Collections.Generic及泛型继承、运算符、结构、接口、方法、委托、事件、可空类型等
一、定义泛型类
void Main()
{
//实例化泛型类时,才指定具体的类型
MyGenericClass<int> MyGeneri = new MyGenericClass<int>();
Console.WriteLine(MyGeneri.InnerT1Object * );
} public class MyGenericClass<T>//<T1,T2,T3>表示多个类型参数
{
private T innerT1Object;
public string LastName;
public MyGenericClass(T item)//构造函数
{
this.innerT1Object = item;
}
public T InnerT1Object//泛型属性
{
get { return innerT1Object; }
}
}
注意:
1、不能假定T提供了什么类型。eg:innerT1Object=new T(),因为T可能根本无公共默认构造函数。除非 class MyGenericClass<T> where T:new()
public class MyGenericClass<T> where T : new()
{
private T innerT1Object = new T();
}
2、可以把T看作继承System.Object的类型:typeof(T),T.ToString()
3、在没有指定约束类型参数的情况下,比较泛型类型值和null,只能使用==或!=。不能对两个类型值变量进行比较。
public bool Compare(T op1, T op2)
{
if (op1 != null && op2 == null)//正确。如果T为值类型,op1!=null始终成立。
{
//…
}
if (op1 == op2)//错误,因为这就假定了T支持==运算符
{
//…
}
}
4、default关键字用于为T赋默认值,而无需考虑其实值类型还是引用类型。
public class MyGenericClass<T>
{
private T innerT1Object = default(T);
}
5、where 关键字用于约束T的类型。
class MyGenericClass<T> where T:Animal
可用的约束有:
- struct :值类型
- class:引用类型
- <baseclass>:此列或者此类的派生类
- <interface>:此接口或者实现此接口
- new():必须具有无参数的公共构造函数。必须为类型的最后得约束。
- 一个类型参数可有多个约束:class Myclass<T> where T: constait1,constrait2
- 各类型参数不同的约束:class Myclass<T1,T2> where T1: constait1,T2:constrait2
- 约束放于继承符之后:class Myclass<T1>:MyBaseCalss,IMyInterface where T: constait
- 一个类型参数用作另一个类型参数的约束,表示T2与T1的类型相同,或T2继承于T1(裸类型约束)class Myclass<T1,T2> where T2: T1
6、泛型类的静态成员只能在类的一个实例中共享:
void Main()
{
StaticDemo<string>.x=;
StaticDemo<int>.x=;
} public class StaticDemo<T>
{
public static int x;
}
二、从泛型类继承
1、泛型类至少与基类有相同的约束,或为基类的子集
public class Farm<T> where T : Animal
{
//...
} public class SuperFarm<T> : Farm<T> where T : SuperCow //SuperCow为Animal的子集
{
//...
}
2、类继承泛型,必须提供所有的类型信息
public class Cards : List<Card> //派生非泛型
{ }
三、定义泛型运算符
public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2)
{ }
四、定义泛型结构
public struct MyStruct<T1, T2>
{
public T1 item1;
public T2 item2;
}
五、定义泛型接口
interface myInterface<T> where T : Animal
{
bool Brea(T animal1, T animal2);
T oldest { get; }
}
实例:
public interface IComparable<T>
{
int CompareTo(T other);
} public class Person : IComparable<Person>
{
public int CompareTo(Person other)
{
return this.name.CompareTO(other.name);
}
}
六、定义泛型方法
1、普通类
public class Defaulter
{
public T GetDefault<T>()
{
return default(T);
}
}
2、泛型类
public class Defaulter<T1>
{
public T2 GetDefault<T2>() where T2 : T1 //泛型方法的参数最好不要与其所在的泛型类的类型参数相同
{
return default(T2);
} public void Process()
{
}
public void Process<T>(T1 op1)//重载方法1
{
} public void Process<T, U>(T1 op1)//重载方法2
{
}
}
七、定义泛型委托
1、通过泛型委托,委托的参数可以在以后定义。
public delegate T1 MyDelegate<T1, T2>(T2 op1, T2 op2) where T1 : T2;
2、常用内置委托:
(1)、Action<T>: 泛型委托。无返回值。 委托的方法可以有1-16个输入参数。Action:无参数无返回值委托。
Action action1 = () => Console.Write("a");
action1(); Action<string> action2 = (p) => Console.Write(p);
action2("b");
利用Action实现线程和界面交互:
private void button1_Click(object sender, EventArgs e)
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction);
ThreadPool.QueueUserWorkItem(waitCallBack, "Action的使用");
} private void AlternationUsingAction(object text)
{
this.Invoke((Action)( () =>
{
button1.Text = text.ToString();
} ));
}
(2)、Func<T>:必须具有返回值。委托的方法可以有0-16个参数输入参数,加一个输出参数。
Func<int, int, string > Func = (a, b) => (a + b).ToString();
Console.Write(Func(1, 2));
(3)、Predicate<T>:就是只接受一个传入参数,返回值为bool类型。
用于搜索方法
public delegate bool Predicate<T>(T obj);//判断条件函数
public T Find(Predicate<T> matach);
举例:
Predicate<string[]> predicate = x =>
{
var result = from p in x
where p.Contains("s")
select p;
return result.ToList().Count > 0; };
string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" };
Console.WriteLine(predicate(_value) ? "包含." : "不包含");
(4)、Comparision<T>(T obj1,T obj2):比较函数,用于搜索方法。
public delegate int Comparision<T>(T obj1,T obj2)//
public void Sort(Comparision<T> comprison)
(5)、EventHandler<TEventArgs>:泛型事件处理函数。
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
3、实例:
public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);//定义泛型委托
public static TSummary Accumulate<TInput, TSummary>(IEnumerable <TInput> cols, Action<TInput, TSummary> action)
//将委托实例action传给方法参数。
{
TSummary sum = default(TSummary);
foreach (TInput input in cols)
{
sum = action(input, sum);//执行委托方法
}
return sum;
} void Main()
{
decimal amount = Accumulate<int, decimal>(new List<int> { , }, (a, b) => a + b);//(a, b) => a + b为委托实例
Console.Write(amount);
}
八、定义泛型事件
事件与委托就像一对孪生兄弟。既然有泛型委托,那么也应该有泛型事件。因为在以前,事件处理函数的发送方参数的类型总是Object。因此事件处理函数没有办法根据不同的发送者身份或者类型对事件进行不同的处理。现在如果使用泛型事件就可以使用强类型的发送方,不再需要强制转换成Object或反向强制转换。而且也可以根据发送方类型的不同对消息进行不同的处理。
例子中演示了发送方是强类型的情况,在这个例子中使用泛型类Publisher<T>来表示消息的发布者,用类Receiver来表示消息的订阅者。
//定义了一个泛型委托,该委托指定了发送者的具体类型
public delegate void MyEventHandler<T>(Publisher<T> Sender); void Main()
{
//事件发布者
Publisher<int> publisherI = new Publisher<int>();
Publisher<double> publisherD = new Publisher<double>(); //事件订阅者
Receiver receiver = new Receiver(); //开始绑定事件
publisherI.Click += receiver.OnClick;
publisherD.Click += receiver.OnClick; //引发事件
publisherI.SendMessage();
publisherD.SendMessage();
} //消息发布者类Publisher<T>的代码
public class Publisher<T>
{
//定义了一个泛型事件,该事件的发布者的类型是强类型
public event MyEventHandler<T> Click; //发送事件函数
public void SendMessage()
{
Click(this);
}
} //消息订阅者类Receiver的代码
class Receiver
{
//事件处理函数,该函数具有强类型的参数表示发送者
public void OnClick(Publisher<int> sender)
{
Console.WriteLine("该事件已经写入日志文件");
} //事件处理函数
public void OnClick(Publisher<double> sender)
{
Console.WriteLine("该事件已经发送到主管信箱");
}
}
九、可空类型System.Nullable<T>
1、声明和赋值
Nullable<int> x = ;//可写成int? x = 4
x = null;//可为可空类型赋值null.
2、判断为空
int y;
if (x.HasValue)//或者x!=null
{
y = x = value;
}
else
{
y = x ?? ;//或者 x.GetValueOrDefault(); x=null则或者其默认值。
}
3、转换
int? op1=;
int? result=op1 *; int? op2=;
int result1=op2 *;//如果op2为null,强制转换int?到int产生异常
十、ArraySegement<T> 数组片段
int[] arr = { , , , , , , , };
ArraySegment<int> segment = new ArraySegment<int>(arr, , );
for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
{
Console.WriteLine(segment.Array[i]);
}
泛型 System.Collections.Generic及泛型继承、运算符、结构、接口、方法、委托、事件、可空类型等的更多相关文章
- C#:system.collections.generic(泛型)
1. array是一个固定长度的,如果要动态的存储的话就不行了,虽然 System.Collections.ArrayList(),是一个动态的存储的容器,但是没有对存储中的数据进行一个约束,所以非泛 ...
- using System.Collections.Generic;
public class CommonClass { public static void ShowInt(int iValue) { //typeof(CommonClass) typeof关键字 ...
- System.Collections.Generic的各容器类的用法
演示System.Collections.Generic的各容器类的用法. 包括:Dictionary,KeyValuePair,SortedDic tionary,SortedList,HashSe ...
- 无法将类型“System.Collections.Generic.List<anonymous type:string ClassID,string ClsssName>”隐式转换为“System.Collections.Generic.List<Ecology.Model.EnergyFlowGraph>”
无法将类型“System.Collections.Generic.List<anonymous type:string ClassID,string ClsssName>”隐式转换为“Sy ...
- Web Service接口返回泛型的问题(System.InvalidCastException: 无法将类型为“System.Collections.Generic.List`1[System.String]”的对象强制转换为类型“System.String[]”)
在使用C#写Web Service时遇到了个很奇怪的问题.返回值的类型是泛型(我用的是类似List<string>)的接口,测试时发现总是报什么无法转换为对象的错误,百思不得其解. 后来在 ...
- NHibernate无法将类型“System.Collections.Generic.IList<T>”隐式转换为“System.Collections.Generic.IList<IT>
API有一个需要实现的抽象方法: public IList<IPermission> GetPermissions(); 需要注意的是IList<IPermission>这个泛 ...
- C# System.Collections.Generic.Dictionary
using System; using System.Collections.Generic; public class Example { public static void Main() { / ...
- System.Collections.Generic.List<T> 与 System.Collections.ArrayList
[推荐] System.Collections.Generic.List<T> [原因] 泛型集合类List<T>在操作值类型的集合时可以不进行 装箱/拆箱 处理. 使得性能较 ...
- Unity3d:Unknown type 'System.Collections.Generic.CollectionDebuggerView'1
问题描述:如图,在调试状态下说:Unknown type 'System.Collections.Generic.CollectionDebuggerView'1<ignore_js_op> ...
随机推荐
- 利用卷积神经网络处理cifar图像分类
这是一个图像分类的比赛CIFAR( CIFAR-10 - Object Recognition in Images ) 首先我们需要下载数据文件,地址: http://www.cs.toronto.e ...
- mysql函数concat与group_concat使用说明
mysql函数concat与group_concat使用说明concat()函数<pre>mysql> select concat(',',name,',') from `user` ...
- php类的继承(基本概念,访问权限修饰符,重写override)
类的继承 简单理解: 某个类A具有某些特征,另一个类B,也具有A类的所有特征,并且还可能具有自己的更多的一些特征,此时,我们就可以实现:B类使用A的特征信息并继续添加自己的一些特有特征信息. 基本概念 ...
- git push时出现大文件的处理方法
最近在提交项目时出现报错 文件限制只能100M,但是里面有个文件202M,超过了码云的限制. 所以顺手就把这个文件删除了 然后发现还是同样的报错,反复检查目录还是不行,找了资料说,需要git rm 命 ...
- Python中遍历整个列表及注意点(参考书籍Python编程从入门到实践)
1. 利用for循环遍历整个列表 magicians = ['alice', 'dsvid', 'carolina'] # 遍历整个列表 for magician in magicians: prin ...
- python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)
9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕详细解释:1.主 ...
- QuartzNet 任务管理系统
最近有面试!都有问道Quartz方面的问题,之前的项目有使用过,也知道怎么用,但面试时要说出它的原理,一时半会还真说不来!查阅了一些资料先记录下来吧 Quartz.NET官网地址:https://ww ...
- AtomicIntegerFieldUpdater和AtomicInteger
为什么有了AtomicInteger还需要AtomicIntegerFieldUpdater? 当需要进行原子限定的属性所属的类会被创建大量的实例对象, 如果用AtomicInteger, 每个实例里 ...
- java 任务定时调度(定时器)
任务定时调度 通过Timer和Timetask,我们可以实现定时启动某个线程. java.util.Timer 在这种实现方式中,Timer类作用是类似闹钟的功能,也就是定时或者每隔一定时间触发一次线 ...
- Python之算法评估-4
一.评估算法的方式分两种,一种是分类算法的评估,一种是回归算法的评估.为什么要分两种呢,因为分类算法中可以通过准确率.精准率.召回率.混淆矩阵.AUC来评估算法的准确度.但是在预测值的时候是没有办法去 ...