C#基础知识系列一(goto、i++、三元运算符、ref和out、String和string、重载运算符)
前言
这两天在网上看到的总结很多,尤其是博客园中的,很多很多,也给了我很多的启发,当然自己也总结过,而且有很多人也给与我一些意见和看法。不管怎样,自己还是先把所谓的基础知识加强巩固下吧。
2014年的第一篇博客,希望自己从基础开始。也是希望自己能够稍微系统来学习整合一下。因为之前从来都没系统学习过,都是用到啥查啥,先查啥就忘啥快,所以在此记录一下,以备以后查看。好了废话也不多说,进入正题。
正文
1、类和对象
类的定义:具有相同属性和功能的对象的抽象的集合。——脑门一闪,类其实也是个集合吗?
类的实例:实例化就是创建对象的过程,使用new关键字来创建。
来看以下代码,最简单的,你肯定懂:
public class Cat { public string Name { get; set; } } class Program { static void Main(string[] args) { Cat cat = new Cat(); } }
就是这句:Cat cat=new Cat();其实它做了两件事情,不知道你们知道不,我是现在才又知道的(原来肯定知道过,不过早已抛在千里之外了):
2、goto:语句将程序控制直接传递给标记语句。
goto貌似在开发中从来没用过。
static void Main(string[] args) { int i = 0; repeat: // the label Console.WriteLine("i: {0}", i); i++; if (i < 10) goto repeat; // the dastardly deed Console.ReadLine(); }
这是一个简单的用法满足条件的时候,跳转到标记repeat;
输出结果:
这有一篇关于goto的详细介绍:包括它的优缺点,应用场景。
http://www.cnblogs.com/IT-Bear/archive/2012/03/05/2380389.html
3、continue、break、return:C#编程语法中我们会经常碰到break ,continue, return这三个常用的关键字
break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句。由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的break语句才是合法的。
如果一个循环的终止条件非常复杂,那么使用break语句来实现某些条件比用一个循环表达式来表达所有的条件容易得多。
for (var i = 1; i <= 10; i++) { if (i == 6) break; Console.WriteLine(i); } //输出结果:12345
continue语句和break语句相似。所不同的是,它不是退出一个循环,而是开始循环的一次新迭代。
continue语句只能用在while语句、do/while语句、for语句、或者for/in语句的循环体内,在其它地方使用都会引起错误!
for (var i = 1; i <= 10; i++) { if (i == 6) continue; Console.WriteLine(i); } //输出结果:1234578910
return语句就是用于指定函数返回的值。return语句只能出现在函数体内,出现在代码中的其他任何地方都会造成语法错误!
当执行return语句时,即使函数主体中还有其他语句,函数执行也会停止!
4、i++和++i,前者先用后加,后者先加后用
这个在学校学的时候就感觉好别扭,现在好久没看了又模糊了。可能这也是面试的时候很多公司愿意出的问题吧。
static void Main(string[] args) { int valueOne = 10; int valueTwo; valueTwo = valueOne++; Console.WriteLine("After postfix: {0}, {1}", valueOne, valueTwo); valueOne = 20; valueTwo = ++valueOne; Console.WriteLine("After prefix: {0}, {1}", valueOne, valueTwo); Console.ReadLine(); }
再来看一个简单的小例子:
int k = 0; int i = 3; k = ++i + (i++); Console.WriteLine("k={0},i={1}", k, i);
先来看如果i=3; return i++; 那么返回的是3;如果return ++i;那么返回的是4。
所以 ++i 现在i=4;表达式变为4+(4++),而4++是先用了再加 所以就是8++,而8++同理先返回8,i再++,i就为5。
当然此题解法可能不止一种,如果你有兴趣可以一起来探讨一下。
5、switch中的case可以这样写
static void Main(string[] args) { const int Democrat = 0; const int LiberalRepublican = 1; const int Republican = 2; int myChoice = LiberalRepublican; switch (myChoice) { case Democrat: Console.WriteLine("You voted Democratic.\n"); break; case LiberalRepublican: case Republican: Console.WriteLine("You voted Republican.\n"); break; default: Console.WriteLine("You did not pick a valid choice.\n"); break; } Console.ReadLine(); }
case LiberalRepublican:
case Republican:
符合这两个条件都会执行:
Console.WriteLine("You voted Republican.\n");
6、三元运算符相当于if else
static void Main( string[] args ) { int valueOne = 10; int valueTwo = 20; int maxValue = valueOne > valueTwo ? valueOne : valueTwo; Console.WriteLine( "ValueOne: {0}, valueTwo: {1}, maxValue: {2}", valueOne, valueTwo, maxValue ); }
int maxValue = valueOne > valueTwo ? valueOne : valueTwo;
这一句等同于一个if else
if (valueOne > valueTwo) { maxValue = valueOne; } else { maxValue = valueTwo; }
7、ref和out:两者都是按地址传递的,使用后都将改变原来参数的数值
rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,rel是有进有出,out是只出不进。
先来看一下ref:其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
示例:
static void Method(ref int i) { i = 44; } static void Main(string[] args) { int val = 0; Method(ref val); Console.WriteLine(val); // val is now 44 Console.ReadLine(); }
传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。
再来看一下out:out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。
示例:
static void Method(out int i) { i = 44; } static void Main(string[] args) { int val; Method(out val); Console.WriteLine(val); // val is now 44 Console.ReadLine(); }
尽管作为 out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。
ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:
但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:
public void SampleMethod( int i) { } public void SampleMethod(ref int i) { }
这样两个方法编译是可以成功的。
8、String和string,之前几乎没区分过这两个,不过还是要注意一下。
在C#中,string 是 System.String 的别名,所以基本上在使用时是没有差别的。习惯上,我们把字符串当作对象时(有值的对象实体),我们用string。
而我们把它当类时(需要字符串类中定义的方法),我们用String,比如:string greet = String.Format("Hello {0}!", place)。
其实乱用也可以,只是这样概念上清楚一点。
另外string是C#保留字,不可用作变量名,String就不是了。 String 必须先引用 System命名空间。
也可以这样理解:string是C#中字符串类型String的反射,一种简化的书写方式,就像int对应于Int32一样,二者在C#中可通用。
再则String是一个类,string是一种数据类型。string是c#中的类,String是.net Framework的类(在c# IDE中不会显示蓝色)
c# string映射为.net Framework的String。如果用string,编译器会把它编译成String,所以如果直接用String就可以让编译器少做一点点工作。
9、重载运算符
先来看几行简单的代码:
static void Main(string[] args) { int x = 5; int y = 6; int sum = x + y; Console.WriteLine(sum); Console.ReadLine(); }
一个int sum=x+y; 加法运算。
稍微封装一下:
static void Main(string[] args) { int x = 5; int y = 6; int sum = Add(x, y); Console.WriteLine(sum); } static int Add(int x, int y) { return x + y; }
如果现在有一个类,需要得知两个类某个属性的和,我们可能会这样:
public class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { this.Name = name; this.Age = age; } } class Program { static void Main(string[] args) { Person p1 = new Person("aehyok", 25); Person p2 = new Person("Leo", 24); int sum = Add(p1.Age, p2.Age); Console.WriteLine(sum); } static int Add(int x, int y) { return x + y; } }
我们再来改动一下:
class Program { static void Main(string[] args) { Person p1 = new Person("aehyok", 25); Person p2 = new Person("Leo", 24); int sum = p1 + p2; Console.WriteLine(sum); } } public class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { this.Name = name; this.Age = age; } public static int operator +(Person p1,Person p2) { return p1.Age+p2.Age; } }
总结
感觉自己的基础有点一塌糊涂吧,好好的补一下。这样一看原来很多基础的东西我从来都不清楚,或者见过然后忘记了。自己在此好好的进行整理总结一下,主要是为了自己复习巩固吧,也希望对某些人有一点作用,当然我的整理中可能存在很多问题,欢迎大牛们来指正。