c#笔记(一)

最近的笔记,C#的一些代码片段。

属性get/set

一般用法:

1
2
3
4
5
6
7
8
9
10
public class Hero  
{
private string name;
public string Name {

get { return name; }
set { name = value; }

}
}

自动属性:

1
2
3
4
public class Hero  
{
public string Name { get; set; }
}

附带其它操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Hero  
{
private string name;
public string Name
{
get {return name;}
set {
if(value.Length <= 10)
{
name = value;
}
}
}
}

扩展方法

定义扩展方法:

1
2
3
4
5
6
7
8
9
public static class Ext
{
public static int ToInt(this string t)
{
int id;
int.TryParse(t, out id);
return id;
}
}

则可以这样调用:

1
2
string a = "1000";
int i = a.ToInt ();

初始化器

定义有一个这样的类:

1
2
3
4
5
6
class Hero
{
public int id;
public string name;
public int lv;
}

对象初始化器:

1
Hero hero = new Hero (){ id = 10, name = "HeroA", lv = 1 };

集合初始化器:

1
2
3
4
5
6
7
8
9
10
11
12
13
List<Hero> Heroes = new List<Hero>
{
new Hero(){ id = 10, name = "HeroA", lv = 1 },
new Hero(){ id = 11, name = "HeroB", lv = 1 },
new Hero(){ id = 12, name = "HeroC", lv = 1 },
};

Dictionary<int, Hero> HeroesDict = new Dictionary<int, Hero>
{
{ 10, new Hero(){ id = 10, name = "HeroA", lv = 1 } },
{ 11, new Hero(){ id = 11, name = "HeroB", lv = 1 } },
{ 12, new Hero(){ id = 12, name = "HeroC", lv = 1 } },
};

匿名类型

1
2
3
4
5
var h1 = new { name = "HeroA", lv = 1 };
var h2 = new[] {
new { name = "HeroA", lv = 1 },
new { name = "HeroB", lv = 2 }
};

委托

委托Delegate定义了方法的类型,委托可传入0~32个参数,可以无返回值,也可以指定返回值类型。

1
2
3
4
5
6
7
8
9
10
public delegate int DelegateTwoInt(int x, int y);

public static int Add(int a, int b)
{
return a + b ;
}

// ...

DelegateTwoInt d = Add;

泛型委托

在定义委托时使用泛型参数,将上边的代码改为泛型委托,同时支持int类型和float类型的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public delegate T DelegateTwoArgs<T>(T x, T y);

public static int intAddFunc(int a, int b)
{
return a + b ;
}
public static float floatAddFunc(float a, float b)
{
return a + b ;
}

// ...

DelegateTwoArgs<int> intAdd = intAddFunc;
int d = intAdd (1, 2);
DelegateTwoArgs<float> floatAdd = floatAddFunc;
float e = floatAdd (0.1f, 0.2f);

为了在其它类中使用委托,必须将委托定义在类的外部。C#中有一些系统已定义好的委托类型,可以直接使用:

Action

Action定义的是返回类型为void的委托类型,有多种重载方式,如果没有传入的参数则使用Action委托,如果有一个参数则可以使用Action<T>委托,同理有Action<T,U>Action<T,U,V>等等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HelloClass
{
public void Hello()
{
Console.WriteLine ("HELLO");
}
public void HelloToName(string name)
{
Console.WriteLine ("HELLO " + name);
}
}

// ...

HelloClass h = new HelloClass ();
Action a1 = h.Hello;
Action<string> a2 = h.HelloToName;

a1 ();
a2 ("World");

Func

Func是有返回值的委托类型,如没有传入参数,使用Func<TResult>,传入一个参数则用Func<T, TResult>,同理还有Func<T, U, TResult>Func<T, U, V, TResult>等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class HelloClass
{
public string Hello()
{
return "HELLO";
}
public string HelloToName(string name)
{
return "HELLO " + name;
}
public string HelloToNameMulti(string name, int times)
{
string ret = "HELLO";
for (int i = 0; i < times; i++) {
ret = ret + " " + name;
}
return ret;
}
}

HelloClass h = new HelloClass ();
Func<string> f1 = h.Hello;
Func<string,string> f2 = h.HelloToName;
Func<string,int,string> f3 = h.HelloToNameMulti;

Predicate

Predicate<T>代表传入一个参数并返回一个bool值的委托类型,通常用lambda表达式来定义。首先用具名的方法来定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PredicateClass
{
public bool isEven(int i )
{
return i % 2 == 0;
}
}


// ...

PredicateClass pClass = new PredicateClass();
Predicate<int> p = pClass.isEven;

List<int> l = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8 };
List<int> even = l.FindAll (p); // {2, 4, 6, 8}

以上的代码如果使用lambda来定义Predicate委托,则应写为:

1
2
3
4
5
6
Predicate<int> p = ( i => i % 2 == 0);

List<int> l = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8 };
List<int> even = l.FindAll (p);

Console.WriteLine (even.Count.ToString());

匿名方法

匿名方法实际上是传递给委托的代码块。使用匿名方法不必创建单独的方法,减少了实例化委托所需的编码系统开销。定义方式为:

1
delegate(参数列表){方法函数体}

在创建匿名方法时会捕获作用范围内的局部变量或参数。

1
2
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

对于传入0个参数的方法,该匿名方法可以省略参数列表,此时该方法可以转换为具有多重签名的委托。

1
2
3
4
5
6
7
8
9
10
11
Action a1 = delegate() {
Console.WriteLine ("Hello");
};

Action<string> a2 = delegate(string s) {
Console.WriteLine ("Hello" + s);
};

Action<string> a3 = delegate {
Console.WriteLine ("Hello");
};

lambda

lambda一定程度上与匿名方法实现相同的功能,且更方便实用。创建lambda表达式时,需要用到lambda运算符(=>),左侧是参数列表,右侧是表达式或代码块,当参数为1个时可省去括号:

1
2
(input-parameters) => expression
(input-parameters) => { statement; }

一个示例:

1
2
3
4
5
6
7
8
9
10
public delegate int DelegateTwoInt(int x, int y);
public delegate int DelegateOneInt(int x);

//...

DelegateOneInt func1 = x => x * x;
DelegateTwoInt func2 = (x, y) => x * y;
DelegateTwoInt func3 = (x, y) => {
return x * x + y * y;
};