1 建立控制台应用程序后
<pre name="code" class="csharp"> #region /定义止跌区域,方便查看 预处理命令
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#endregion
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello");
Console.ReadKey(); //相当于c++ system("pause")
}
}
}
2. 使用简单类型的变量
命名规则:下面是camelCase变量名:age firstName timeOfDeath 下面是PascalCase变量名:Age LastName WinterOfDiscontent Microsoft建议:对于简单的变量,使用camelCase 规则,而对于比较高级的命名则使用PascalCase
例外:
逐字指定的字符串在文件名中非常有用,因为文件名中大量使用了反斜杠字符。如果使用一般的字符串,就必须在字符串中使用两个反斜杠,例如:"C:\\Temp\\MyDir\\MyFile.doc" 而有了逐字指定的字符串字面值,这段代码就更便于阅读。下面的字符串与上面的等价:@"C:\Temp\MyDir\MyFile.doc"
用户输入 类型转换
double n1, n2;
string str;
Console.WriteLine("enter your name:");
str = Console.ReadLine();
n1 = Convert.ToDouble(Console.ReadLine());
n2 = Convert.ToDouble(Console.ReadLine());
命名空间
using LT = ConsoleApplication1.LevelTwo;
namespace ConsoleApplication1
{
using LT = LevelTwo;
namespace LevelTwo
{
namespace LevelTwo
{
}
}
}
3.数组 foreach
int[] myIntArray1 = { 5, 9, 10, 2, 99 };
int[] myIntArray2 = new int[5] { 5, 9, 10, 2, 99 };
for (int i = 0; i < myIntArray2.Length; i++)
{
Console.WriteLine(myIntArray2[i]);
}
int[,] hill = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };
foreach (double height in hill)
{
Console.WriteLine("{0}", height);
}
数组的数组
int [][]jaggedIntArray1 = new int[3][] { new int[] { 1, 2, 3 }, new int[] { 1 },
new int[] { 1, 2 } };
int[][] jaggedIntArray2 = { new int[] { 1, 2, 3 }, new int[] { 1 },
new int[] { 1, 2 } };
foreach(int[] divisorOfInt in jaggedIntArray2 )
{
foreach (int data in divisorOfInt)
{
Console.WriteLine(data);
}
}
4. string字符串
<span style="white-space:pre"> </span> string str = " this is a test .";
char[] c = str.ToCharArray(); //char 数组
foreach (char cha in c)
Console.WriteLine(cha);
Console.WriteLine(str);
Console.WriteLine(str.Length); //长度
str = str.Trim(); //去除头部空格
str = str.ToUpper(); //大写形式
Console.WriteLine(str);
char[] trimChar = { ' ', 'H', 'T','A','.' }; //去掉开头和结尾的其他字符
str = str.Trim(trimChar);
str = str.PadLeft(2); //左侧添加空格
Console.WriteLine(str);
string[] mywords;
mywords = str.Split(' '); //string数组,在指定位置分隔开
foreach(string word in mywords)
{
Console.WriteLine(word);
}
5.函数
一般采用PascalCase形式编写函数名。
static void MyWrite()
{
Console.WriteLine("hello");
}
static void Main(string[] args)
{
MyWrite();
}
6.参数数组
C#允许为函数指定一个(只能指定一个)特定的参数,这个参数必须是函数定义中的最后一个参
数,称为参数数组。参数数组可以使用个数不定的参数调用函数,可以使用params关键字定义它们。
static int MaxValue(string str,params int[] myArray )
{
Console.WriteLine(str);
int max = myArray[0];
for (int i=1;i<myArray.Length ;i++ )
{
if (myArray[i] > max)
max = myArray[i];
}
return max;
}
static void Main(string[] args)
{
int max = MaxValue("hello",1,5,2,9,8); //params 特定参数
Console.WriteLine(max);
}
7.引用传值
用作ref 参数的变量有两个限制。首先,函数可能会改变引用参数的值,所以必须在函数调用
中使用“非常量”变量。其次,必须使用初始化过的变量。C#不允许假定ref 参数在使用它的函数中初始化
static int ShowDouble(ref int data ) //ref
{
data *= 2;
return data;
}
static void Main(string[] args)
{
int max = 5;
ShowDouble(ref max); //再次ref
Console.WriteLine(max);
}
8.输出参数
与ref 区别如下:
1)把未赋值的变量用作ref参数是非法的,但可以把未赋值的变量用作out参数。
2)另外,在函数使用out参数时,out参数必须看作是还未赋值。
static int ShowDouble(out int data) //out
{
data = 2;
return data;
}
static void Main(string[] args)
{
int max = 5;
ShowDouble( out max); //out
Console.WriteLine(max);
}
9. static 全局变量
在这种类型的控制台应用程序中,必须使用static或const关
键字,来定义这种形式的全局变量。如果要修改全局变量的值,就需要使用static,因为const禁止
修改变量的值。
10.结构函数
<pre name="code" class="csharp"> using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
struct NewClass
{
public string name1, name2;
public string name()
{
return name1 + " " + name2;
}
}
class Program
{
static void Main(string[] args)
{
NewClass newclass;
newclass.name1 = "hello";
newclass.name2 = "world";
Console.WriteLine(newclass.name());
}
}
}
11.函数的签名包含函数的名称及其参数 函数的返回值类型不是签名的一部分,所以不能定义两个仅返回类型不同的函 数,它们实际上有相同的签名。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
<span style="color:#33ffff;"> delegate string MyName(string s1,string s2);
static string addstring(string s1,string s2)
{
return s1 + " " + s2;
}
static void Main(string[] args)
{
MyName name = new MyName(addstring);
Console.WriteLine(name("hello","world"));
}</span>
}
}
12. vs调试技巧
设置断点后右击
条件 : 对话框供你设置激活该断点所需的条件。
命中次数 : 只有当第N次满足条件的运行到达断点时,才中断程序运行。
命中条件 :一旦命中断点时就打印追踪信息
13.
try{}
catch(<exceptionType> e){}
finally{}
如果try块里的语句执行那么就跳过catch块执行finally块
如果try块里的语句不执行那么就执行catch块然后再执行finally块
也就是说无论什么情况 finally块里的语句都必须要执行
见的最多的就是ADO.NET里的finally{ conn.close(); }
关闭数据库链接
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Spacing added here so that line numbers match with the chapter description.
namespace Ch07Ex02
{
class Program
{
static string[] eTypes = { "none", "simple", "index", "nested index" };
static void Main(string[] args)
{
foreach (string eType in eTypes)
{
try
{
Console.WriteLine("Main() try block reached."); // Line 23
Console.WriteLine("ThrowException(\"{0}\") called.", eType); // Line 24
ThrowException(eType);
Console.WriteLine("Main() try block continues."); // Line 26
}
catch (System.IndexOutOfRangeException e) // Line 28
{
Console.WriteLine("Main() System.IndexOutOfRangeException catch"
+ " block reached. Message:\n\"{0}\"",
e.Message);
}
catch // Line 34
{
Console.WriteLine("Main() general catch block reached.");
}
finally
{
Console.WriteLine("Main() finally block reached.");
}
Console.WriteLine();
}
Console.ReadKey();
}
static void ThrowException(string exceptionType)
{
Console.WriteLine("ThrowException(\"{0}\") reached.", exceptionType); // Line 49
switch (exceptionType)
{
case "none":
Console.WriteLine("Not throwing an exception.");
break; // Line 54
case "simple":
Console.WriteLine("Throwing System.Exception.");
throw (new System.Exception()); // Line 57
case "index":
Console.WriteLine("Throwing System.IndexOutOfRangeException.");
eTypes[4] = "error"; // Line 60
break;
case "nested index":
try // Line 63
{
Console.WriteLine("ThrowException(\"nested index\") " +
"try block reached.");
Console.WriteLine("ThrowException(\"index\") called.");
ThrowException("index"); // Line 68
}
catch // Line 70
{
Console.WriteLine("ThrowException(\"nested index\") general"
+ " catch block reached.");
//throw;
}
finally
{
Console.WriteLine("ThrowException(\"nested index\") finally"
+ " block reached.");
}
break;
}
}
}
}
14.类的UML表示方法
在顶部,实例名显示在前面,后面是类名。这两个名称用一个冒号分隔。
用第二部分显示属性和字段,+号表示公共成员,-号表示私有成员,
成员名。
成员的类型。冒号用于分隔成员名和类型。
方法显示在第三部分.其语法类似于字段和属性,但最后显示的类型是返回类型,在这一部分,还显示了方法的参数。
在UML中,每个参数都带有下述标识符之一:in、out或inout。它们用于表示数据流的方向,
15. winforms 程序
16.类定义using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Text = "clicked";
<span style="color:#33ffff;"> Button newButton = new Button(); //添加按钮</span>
<span style="color:#33ffff;"> newButton.Text = "new button";</span>
<span style="color:#33ffff;"> newButton.Click += new EventHandler(newButton_Click);</span>
<span style="color:#33ffff;"> Controls.Add(newButton);</span>
}
private void newButton_Click(object sender, EventArgs e) //自定义
{
((Button)sender).Text = "Clicked";
}
}
}
默认情况下,类声明为内部的,即只有当前项目中的代码才能访问它.
在C#的类定义中,只能有一个基类,如果继承了一个抽象类,就必须实现所继承的所有抽象成员(除非派生类也是抽象的)。 (含有或继承一个或多个纯虚函数的类是抽象基类。 abstract)
编译器不允许派生类的可访问性高于基类
如果指定了基类,它必须紧跟在冒号的后面,之后才是指定的接口.
17.接口定义abstract或internal abstract 类只能在当前项目中访问,不能实例化,只能供继承之用. sealed或internal sealed 类只能在当前项目中访问,不能供派生之用,只能实例化. public class MyClass : MyBase, IMyInterface, IMySecondInterface //MyBase为基类 后两个为接口 { }
与类一样,接口也默认定义为内部接口(internal)。所以要使接口可以公开访问,必须使用public关键字:
接口的继承也可以用与类继承类似的方式来指定。主要的区别是可以使用多个基接口。
18. 类库项目publicinterface IMyInterface { // Interface members. }
创建一个“类库”(Class Library)类型的新项目
public class MyExternalClass
{
}
internal class MyInternalClass
{
}
可以选择“生成 生成解决方案”(Build ➪Build Solution)菜单项来生成它】。
再创建一个新的控制台应用程序项目。
选择“项目 添加引用”菜单项,或者在“解决方案资源管理
器”(Solution Explorer)窗口中右击“引用”(References),选择相同的选项。
单击Browse按钮,导航到C:\BegVCSharp\Chapter09\Chapter09\Ch09ClassLib\bin\Debug\,双击Ch09ClassLib.dll。
修改Program.cs中的代码
<span style="font-family: monospace; white-space: pre;">using System; </span>
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ch09ClassLib;
namespace Ch09Ex02
{
class Program
{
static void Main(string[] args)
{
MyExternalClass myObj = new MyExternalClass();
Console.WriteLine(myObj.ToString());
Console.ReadKey();
}
}
}
19.结构类和类
结构是值类型,而类是引用类型。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
</pre><span style="font-family:monospace"><span style="white-space:pre"></span></span><pre name="code" class="csharp">namespace Ch09Ex03
{
class MyClass
{
public int val;
}
</pre><span style="font-family:monospace"><span style="white-space:pre"></span></span><pre name="code" class="csharp"> struct myStruct
{
public int val;
}
</pre><span style="font-family:monospace"><span style="white-space:pre"></span></span><pre name="code" class="csharp"> class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
}
结果为 objectA.val = 20;
objectB.val = 20; //引用
structA.val = 30;
structB.val = 40; //值
20.字段关键字readonly static
字段也可以使用关键字readonly,表示这个字段只能在执行构造函数的过程中赋值,或由初始
化赋值语句赋值。
class MyClass
{
public static int MyInt;
}
静态字段必须通过定义它们的类来访问(在上面的示例中,是MyClass.MyInt)
21.方法关键字 override
override——方法编写了一个基类方法(如果方法被重写,就必须使用该关键字)。
22.属性
public int MyIntProp
{
get
{
// Property get code.
}
set
{
// Property set code.
}
}
23.接口定义
接口成员的定义与类成员的定义相似,但有几个重要的区别:
不允许使用访问修饰符(public、private、protected或internal),所有的接口成员都是公共的。
接口成员不能包含代码体。
接口不能定义字段成员。
接口成员不能用关键字static、virtual、abstract或sealed来定义。
类型定义成员是禁止的
实现接口的类必须包含该接口所有成员的实现代码,且必须匹配指定的签名(包括匹配指定的get和set块),并且必须是公共的。
可以使用关键字virtual或abstract来实现接口成员,但不能使用static或const。
24.构造函数 执行序列using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
</pre><pre name="code" class="csharp">namespace Ch07Ex02
{
public interface IMyInterface
{
void DoSomething();
void DoSomethingElse();
}
</pre><pre name="code" class="csharp"> public class MyClass : IMyInterface
{
public void DoSomething()
{
}
public void DoSomethingElse()
{
}
}
}
</pre><pre name="code" class="csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
</pre><pre name="code" class="csharp">namespace Ch07Ex02
{
class Program
{
static void Main(string[] args)
{
MyClass myObj = new MyClass();
myObj.DoSomething();
IMyInterface myInt = myObj;
myInt.DoSomething();
}
}
}
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass() : this(5, 6)
{
}
...
public MyDerivedClass(int i, int j) : base(i)
{
}
}
这段代码将执行下述序列:
执行System.Object.Object构造函数。
执行MyBaseClass.MyBaseClass(int i)构造函数。
执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。
执行MyDerivedClass.MyDerivedClass()构造函数。
25.集合
(1) ArrayList
using System.Collections;
ArrayList animalArrayList = new ArrayList();
int a = 1;
animalArrayList.Add(a);
animalArrayList.Add(2);
animalArrayList.RemoveAt(0); //删除
ArrayList animalArrayList2 = new ArrayList();
animalArrayList2.Add(3);
animalArrayList.AddRange(animalArrayList2); //包含
foreach (int mydata in animalArrayList)
{
Console.WriteLine(mydata.ToString());
}
(2) IList CollectionBase 定义集合 索引符
namespace ConsoleApplication1
{
public class Animal: CollectionBase
{
public void Add(Animal newAnimal)
{
List.Add(newAnimal); //定义集合
}
public void Remove(Animal oldAnimal)
{
List.Remove(oldAnimal);
}
public Animal()
{
}
public Animal this[int index]
{
get
{
return (Animal)List[index];
}
set
{
List[index] = value;
}
}
}
}
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Animal animals = new Animal();
animals.Add(new Cow("sarah"));
}
}
}
(4)迭代器
在迭代器块中,使用yield关键字选择要在foreach循环中使用的值。其语法如下:
yield return <value>;
public static IEnumerable SimpleList()
{
yield return "string 1";
yield return "string 2";
yield return "string 3";
}
static void Main(string[] args)
{
foreach (string item in SimpleList())
Console.WriteLine(item);
Console.ReadKey();
}
结果:
"string 1";
"string 2";
"string 3";
IDictionary接口,允许项通过关键字值(如字符串名)进行索引,而不是通过一个索引
public void Add(string newID, Animal newAnimal)
{
Dictionary.Add(newID, newAnimal);
}
public void Remove(string animalID)
{
Dictionary.Remove(animalID);
}
public Animals()
{
}
public Animal this[string animalID]
{
get
{
return (Animal)Dictionary[animalID];
}
set
{
Dictionary[animalID] = value;
}
}
public new IEnumerator GetEnumerator()
{
foreach (object animal in Dictionary.Values)
yield return (Animal)animal;
}
(5)浅复制 System.Object.MemberwiseClone(
public class Contents
{
public int ival;
}
public class Cloner
{
public Contents mycontents = new Contents();
public Cloner(int newVal)
{
mycontents.ival = newVal;
}
public object GetCopy()
{
return MemberwiseClone();
}
}
static void Main(string[] args)
{
Cloner mysource = new Cloner(5);
Cloner mytarget = (Cloner)mysource.GetCopy();
Console.WriteLine(mytarget.mycontents.ival);
mysource.mycontents.ival = 2;
Console.WriteLine(mytarget.mycontents.ival);
}
(6)深复制 基类ICloneable
public class Contents
{
public int ival;
}
public class Cloner :ICloneable
{
public Contents mycontents = new Contents();
public Cloner(int newVal)
{
mycontents.ival = newVal;
}
public object Clone()
{
Cloner cloner=new Cloner(mycontents.ival);
return cloner;
}
static void Main(string[] args)
{
Cloner mysource = new Cloner(5);
Cloner mytarget = (Cloner)mysource.Clone();
Console.WriteLine(mytarget.mycontents.ival);
mysource.mycontents.ival = 2;
Console.WriteLine(mytarget.mycontents.ival);
}
(7)
public class Cards : ICloneable
{
public object Clone()
{
return MemberwiseClone();
}
}
public class Cards : CollectionBase, ICloneable
{
public object Clone()
{
Cards newCards = new Cards();
foreach (Card sourceCard in List)
{
newCards.Add(sourceCard.Clone() as Card);
}
return newCards;
}
}
public class Deck : ICloneable
{
public object Clone()
{
Deck newDeck = new Deck(cards.Clone() as Cards);
return newDeck;
}
}