泛型 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> ...
随机推荐
- NAT的配置
实验的拓扑图如下所示 首先我们对路由器进行基础的地址配置 我们先在R2路由器上设置一条连接外网的静态路由 然后我们给PC1设置一个静态NAT 然后使得PC1 通过202.169.10.5 地址访问外网 ...
- JS Maximum call stack size exceeded
一.问题描述 Maximum call stack size exceeded 翻译为:超过最大调用堆栈大小 二.效果截图 三.问题解决方案 出现该问题,说明程序出现了死循环了.所以要去检查出错的程 ...
- PHP强制在微信中打开
if (!Func::isWx()) { exit('请在微信客户端打开链接'); } // 判断是否是微信 public static function isWx() { if ( strpos($ ...
- WCF-方法重载
一.服务端重载 一般写法直接重载,但是会报错,如下. [ServiceContract] public interface IService1 { [OperationContract] string ...
- laravel框架视图中常用的逻辑结构forlese,foreach,ifelse等
if 和else @if($name === 1) 这个数字是1 @else 这个数字非1 @endif switch @switch($name) @case(1) 变量name == 1 @bre ...
- Python进阶:生成器--懒人版本的迭代器
从容器.可迭代对象谈起 所有的容器都是可迭代的(iterable),迭代器提供了一个next方法.iter()返回一个迭代器,通过next()函数可以实现遍历. def is_iterable(par ...
- WUSTOJ 1305: 最短路(Java)
题目链接:
- C#中使用XML存储数据
创建XML文档 首先引用System.Xml命名空间 1.初始化一个实例 XmlDocument xd = new XmlDocument(); 2.创建XML头文件声明 XmlDeclaration ...
- Win32小游戏--贪吃蛇
近日里学习了关于win32编程的相关知识,利用这些知识制作了一款贪吃蛇小游戏,具体细节还是分模块来叙述 前期准备:在网上找到一些贪吃蛇的游戏素材图片,以及具体的逻辑框图 在正式写功能之前,先把一系列环 ...
- 『Python基础』第20节:深浅copy
一. 赋值运算 l1 = [1, 2, 'conan', [11, 22]] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 'conan', [11, 22]] p ...