c#入门经典(2)(202)

泛型

default

由于泛型T不确定是值类型还是引用类型,所以
T a = null这句是错误的(值类型就空了)。

T a = default(null)这样的话值类型就是0,引用类型就是null

yield

这个一般是yield return, yield break联合使用;如下

1
2
3
4
5
6
7
8
9
IEnumerable<int> SName(int a)
{
yield return 1;
yield return 3;
yield return 6;
yield break;
}
//注意返回值必须是 IEnumerable 或 IEnumerator
//好像说这种方法比在函数里面push或add更有效

c#遍历属性

我今天想遍历一个类的属性,发现必须满足以下几点:

  1. 必须是属性,不能是成员。
  2. 必须是public

满足以上后才能用循环到:

1
2
3
T tdata = new T();
PropertyInfo[] userpros = tdata.GetType().GetProperties();
foreach (var pro in userpros) {}

where约束

这个我不是很深,以后补充;先看段代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class MyBase<T>
where T: class
, new() {
public MyBase() {
Console.WriteLine("base");
}
public MyBase(int n)
:this() {
Console.WriteLine("base");
}
public virtual T ShowD() {
Console.WriteLine("MyBase");
T b = new T();//这里很重要
return b;
}
}
class MyDrive<D> : MyBase<D>, IEnumerable
where D: class, new() {
public MyDrive()
: base(3) {
Console.WriteLine("Drive");
}
public MyDrive(int a)
{ }
public override D ShowD() {
Console.WriteLine("MyDrive");
D b = new D();//这句很重要
return b;
}
}
MyDrive<Program> my = new MyDrive<Program>(3);//调用

第一个类;where对T约束为引用类型(值类型可以用struct),这样调用<>里面就只能是引用类型了
除此外where还约束为new(),表示<>里的类型必须有默认的构造函数,这样才可以用new T()这样的代码(测试发现里面不能加参数)

where还可以准确约束,有点像c++的模板特例化

协变和抗变

http://blog.csdn.net/sudazf/article/details/17148971

可空类型及运算符

可空类型原型是System.Nullable<T>,简单型T?
网上说它是为了sql设计
操作符可以和原型相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//??是判断是否为空
int? x = 3;
int y = x ?? 5;//y:3
x = 0;
y = x ?? 6;//x:0 y:0
x = null;
y = x ?? 7;//x:null y:7
//再看运算符应用(好像它只能用于引用类型,不能用于值类型)
public static string DoQG(dynamic dy)
{
string result = dy.GG();
return result ?? "hehe";
}
MyClass hh = new MyClass();
YouClass yy = new YouClass();
MyClass sss = yy ?? null;

各个泛型容器及性能

队列Queue
栈Statck
链表LinkedList
有序列表SortedList, IComparef接口用于排序
字典Dictionary 无排序 键类型需要实现GethashCode和IEquatable
有序字典SortedDictionary
集 HashSet
有序集 SortedSet

书上本来是有个性能表,但是纠结了感觉没啥用,就不写等以后更新。

接口

1
2
3
public internal IMyInter{
void Do();
}

暂时看它和虚基类没啥区别呀!!!!!!以后再加吧。

foreach的自定义

自定义类要使用foreach,就必须实现IEnumerator和IEnumerable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyDrive : IEnumerable
{
public IEnumerator GetEnumerator()
{ return new MyTor(); }
class MyTor : IEnumerator
{
public bool MoveNext() { return true; }
public void Reset() { }
public object Current { get { return null; } }
}
}
MyDrive ss = new MyDrive();
foreach (var t in ss) {}

排序搜索等

本以为较简单的,看了下发现和其它还有关,就记录了。
两种:
IComparable在要比较的对象类中实现,可以比较该对象和另一对象
IComparer在一个单独的类中实现,可以比较任意俩个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Person : IComparable
{
public string Name;
public int Age;
public Person (string s, int i)
{
Name = s;
Age = i;
}
public int CompareTo(object obj)
{
if (obj is Person)
{
Person ot = obj as Person;
return ot.Age - this.Age;
}
return 1;
}
}
public class PersonCompareName : IComparer
{
public int Compare(object x, object y)
{
if (x is Person && y is Person)
{
return Comparer.Default.Compare(
((Person)x).Name,
((Person)y).Name);
}
return 0;
}
}
static void Main(string[] args)
{
List<Person> asa = new List<Person>();
asa.Add(new Person("nam1", 1));
asa.Add(new Person("nam2", 2));
asa.Add(new Person("nam3", 3));
asa.Sort();//排序会进行比较,这个比较会调用IComparable的CompareTo
PersonCompareName ii = new PersonCompareName();
asa.Sort(ii.Compare);//这个排序比较会调用IComparer的Compare
}
其它接口
  • 搜索
    如同排序,搜索本身是Predicate继承,传入的话直接一个static函数就好了。
    搜索可以返回数组

  • 字典
    Dictionary,这个字典缺点就是添加的键值不能相同,同了就抛出异常。
    所以每次add要判断是否存在,感觉好麻烦!

添加元素 AddRange(),IEnumerable
删除元素 RemoveAt,IEquatable接口
搜索元素 IndexOf、LastIndexOf()、FindIndex()、FindLastIndex()、Find()、FindLast(),IEquatable接口
排序元素 Sort()、Comparison和IComparer前面已讲

// //