当前位置:编程学习 > C#/ASP.NET >>

C#初学笔记

毕业设计要用到c#。
在学过了c++和java后,初看《c#入门经典》和《c#高级编程》,不免在心里把c#和java与c++在语法方面做些比较,做些笔记。

预编译:
像C++一样,c#中有预编译命令

namespace 和 using:
还搞不太懂,和java中import有些相同

基本和数据类型:
像c++中一样有unsigned类型,如uint,ushort等等

goto:
java中被废掉的goto关键字又回来了

const:
定义常量用const关键字;

@:
@符号后面的字符串就是字面的意思(没有转移字符),比如string s = @"\n" 这s就是"\n"而不是一个换行符

foreach:
如int[] intArray = new int[3];foreach(int i in intArray){...}

switch:
可以用于string;default不一定要写在最后一句,但只有在没有case匹配时才会执行;每个case必须有break或return或goto case ...结束,两个或多个case连续写在一起的情况除外

enum:
默认的underlying type是int,从0开始赋值,可以像int一样进行运算,也可以和int相互转换。underlying type也可以是其他的基本数据类型,也可以自己赋值。
01
enum Orientation:byte
02
{
03
    east,
04
    west=3,
05
    north,
06
    south=north
07
}
08
...
09
Orientation o = Orientation.south;          
10
int i = (byte)o;
11
Orientation east = (Orientation)0;
12
Orientation direction = (Orientation)Enum.Parse(typeof(Orientation), "north");//字符串转化为枚举
typeof:
typeof(Object)感觉像java里面的Object.class;object.GetType()像java里面的object.getClass();

struct:
结构派生于System.ValueType,它又派生于System.Object
结构体struct和class很像,同样可以有属性和方法,也可以实现接口,但struct是值类型,而class是引用类型
1
MyStruct struct1 = new MyStruct();
2
MyStruct struct2 = struct1;
3
//struct1复制了一份给struct2,对struct2的设置不会影响struct1
4
MyClass class1 = new MyClass();
5
MyClass class2 = class1;
6
//对class2的修改会影响class1,因为它们指向同一个实例
ref,out:
ref使得参数按引用传递

1
void Triple(ref int a)
2
{a *= 3;}
3
...
4
int a = 3;
5
Triple(ref a);
6
Console.WriteLine(a);//a变成9
out和ref功能和用法相同,区别在于用ref传入函数的参数必须先初始化,out不用

params:
params关键字使函数可以接受个数任意的参数
int fun(params int[] a)就像java中的int fun(int...a)

Main函数:
有4种static int Main(string[]args),static void Main(string[]args),static int Main(),static void Main()


易做图数组,变长数组:

1
int[][] array = new int[3][];// 变长数组          
2
array[0] = new int[3];
3
array[0][1] = 43;
4
 
5
int[,] array2 = new int[4, 5];//易做图数组
6
array2[0, 1] = 32;
而java中都是变长数组,即数组的数组

checked和unchecked:
使用checked会在溢出是抛出异常,默认是unchecked

1
byte b = 255;
2
checked { b++; }//抛出异常
3
Console.WriteLine(b);
 

delegate:
委托(代理)好像就是c++中的函数指针,委托也是一种类,派生于System.MulticastDelegate

1
int add(int a,int b){return a+b;}
2
int subtract(int a,int b){return a-b;}
3
delegate int Fun(int a,int b);
4
Fun f = add;
5
int a = f(1,1);//得到2
6
f=subtract;
7
int b = f(1,1);//得到0
多播委托可以使用+、-、+=、-=运算符

集合:
Array和ArrayList等都用中括号[]来索引,Dictionary还可以用任意类型的引索(这让我想到了js)

1
Dictionary<string, int> dic = new Dictionary<string, int>();
2
List<int> l = new List<int>();
3
...
4
int a = (int)al[0];
5
int b = dic["haha"];
 

函数重载:
virtual显式指定虚函数或虚属性。不用virtual则默认不是虚拟的(这和C++一样,而java则默认都是虚拟的)。
override关键字用于重载虚函数,new关键字用于显式声明子类的函数隐藏了父类的同名函数。

01
class A
02
{
03
    public void M() { Console.WriteLine("a"); }
04
    public virtual void V() { Console.WriteLine("a"); }     
05
}
06
class B : A
07
{
08
    public new void M() { Console.WriteLine("b"); }
09
    public override void V() { Console.WriteLine("b"); }
10
}
11
...
12
A a = new B();
13
B b = new B();
14
a.M();//a
15
a.V();//b
16
b.M();//b
17
b.V();//b
虚函数的调用取决于实例的类型,而非虚函数的调用取决于引用变量的类型
试了一下发现verride不能和virtual一起用,但如果将来有一个C类要重载B类的V()方法,怎么使B.V()成为虚函数啊?


操作符重载:
重载的方法和C++中的一样(记得学C++时我最喜欢这个了,很方便啊),但限制比C++多。比如必须声明为public和static;不能重载“+=”,重载“+”之后“+=”自然可以使用;不能重载“=”;可以重载“&”,不能重载“&&”;“<”和“>”、“<=”和“>=”、“!=”和“=”要成对重载,不能只重载一个;而且好像只能重载成静态static的。

1
class Time
2
{
3
    public int hour, min;
4
    public Time(int h, int m) { hour = h; min = m; }
5
    public static Time operator +(Time a, Time b)
6
    { return new Time(a.hour + b.hour, a.min + b.min); }
7
}
 

自定义数据类型转换:
很强大啊,用法像重载操作符一样,同样必须是public static。可以在类和基本数据类型之间,类和类之间转换。implicit说明可以隐式转换,explicit指明必须显示转换。转换函数必须写在源类型或目标类型的类或结构体定义里面,有继承关系的本来就可以转换的类之间不能重载。

01
class C
02
{
03
    public int x;
04
    public C(int i) { x = i; }
05
    public static implicit operator int(C c) { return c.x; }
06
    public static explicit operator C(int i) { return new C(i); }
07
}
08
...
09
int i = new C(3);//i=3
10
C c = (C)5;//c.x=5
11
byte b = (byte)new C(2);//b=2,C被转换成int类型后被转换成byte
 

boxing和unboxing:
在引用类型和值类型之间相互装换,boxing是自动进行的,而unboxing是要显式说明的

1
int i = 0;
2
object o = i;//i被自动装箱成引用类型o
3
string str = 2.ToString();//2被被自动装箱成一个临时的引用类型
4
int b = (int)o;//取消装箱
5
Console.WriteLine(Object.ReferenceEquals(i,i));
6
//值类型用ReferenceEquals(a,b)函数进行比较总是得到false,因为装箱之后的引用变量指向了原来值类型变量的一份拷贝,而不是原值。这样对装箱对象的操作不会影响原来的值类型的内容。
《C#高级编程》上的意思是:定义结构体时,.Net Framework会隐式的提供一个隐式类,与结构体相同,却是一个引用类型,用于装箱。枚举类型也有类似情况。

is和as:
“is”和java中的“instanceof”相当;as用于尝试类型转换

1
ClassA a = (ClassB)b;//无法转换时可能抛出异常
2
ClassA a = b as ClassA//无法转换时a=null

事件:
事件处理时c#使用委托,感觉概念上和OOP思想不太相符,不如java中易做图的概念清晰。

关于类的可见性:
protected——只能由类或派生类的访问
internal——只能由定义它的

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,