1.在 C# 中,使用 ref 关键字声明引用参数。
说明变量是引用,在调用该方法时,还需要添加ref关键字。
public void swap(ref int x, ref int y)
{
}
swap(ref x, ref y);
2. out 按输出传递参数
return 语句可用于只从函数中返回一个值。但是,可以使用 输出参数 来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
public void getValues(out int x, out int y )
{
}
getValues(out x, out y);
3.C# 属性(Property)
属性(Property) 是类(class)、结构(structure)和接口(interface)的命名(named)成员。类或结构中的成员变量或方法称为 域(Field)。
属性(Property)是域(Field)的扩展,且可使用相同的语法来访问。
它们使用 访问器(accessors) 让私有域的值可被读写或操作。
属性(Property)不会确定存储位置。相反,它们具有可读写或计算它们值的 访问器(accessors)。
例如,有一个名为 Student 的类,带有 age、name 和 code 的私有域。
我们不能在类的范围以外直接访问这些域,但是我们可以拥有访问这些私有域的属性.
class Student
{
private string code = "N.A";
// 声明类型为 string 的 Code 属性
public virtual string Code
{
get
{
return code;
}
set
{
code = value;
}
}
}
Student s = new Student();
// 设置 student 的 code、name 和 age
s.Code = "001";
4.静态构造函数
struct rectangle
{
public int nweight;
public int nheight;
public rectangle(int weight, int height)
{
nweight = weight;
nheight = height;
}
}
rectangle re = new rectangle(); //调用的就是隐式的无参数的构造函数,
//值类型的字段赋值0,给引用类型的字段赋值null
re.nweight = 1;
re.nheight = 1;
rectangle re = new rectangle(3,5); //调用的就是显式有参数的构造函数
rectangle re2;
int nn = re2.nweight; //报错,因为此种方式创建结构体对象,没有调用构造函数。需要手动设置
re2.nweight =2;
在C#中实例化一个对象时,需要经历下面这几步:
声明引用;
使用new关键字创建类的对象并对其初始化;(分配内存空间)
将引用指向类的对象。
若没有使用new关键字创建类的实例,则仅仅创建引用,指向的对象为null。
注意:c#的函数中new的的对象不需要手动delete。因为.NET有专门的垃圾收集器。
A a = new A();(1)
B b = null;(2) 声明引用b,并指向null。
C c;(3) 声明的引用c不指向任何对象
class CWorkbase
{
public virtual void add()
{
}
}
class CWorkchild : CWorkbase
{
public override void add()
{
int a = 1;
base.add();
}
}
抽象类和抽象函数
abstract class Shape
{
abstract public int area();
}
class Rectangle: Shape
{
private int length;
private int width;
public Rectangle( int a=0, int b=0)
{
length = a;
width = b;
}
public override int area ()
{
Console.WriteLine("Rectangle 类的面积:");
return (width * length);
}
}
在c++中,抽象函数称为纯虚函数。抽象类没有关键字abstract.
sealed class CWorkbase1
{
}
class CWorkbase
{
public virtual void add1()
{
int a = 2;
}
}
class CWorkchild : CWorkbase
{
public sealed override void add1()
{
int a = 3;
}
}
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。
不能实例化接口。接口既不能有构造函数,也不能有字段(应该是成员变量吧)
接口成员总是公有的,不能声明为虚拟或静态。
一个接口可以继承其他接口,接口也可以让类来继承。如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。
不允许提供接口中任何成员的实现方式(即只声明,不实现,实现在继承的类中实现)
using System;
interface IParentInterface
{
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface
{
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
c#泛型和c++的模板相似。
泛型类:
class BaseNode { }
class BaseNodeGeneric { }
// concrete type
class NodeConcrete : BaseNode { }
//closed constructed type
class NodeClosed : BaseNodeGeneric { }
//open constructed type
class NodeOpen : BaseNodeGeneric { }
泛型方法
泛型方法是通过类型参数声明的方法。
static void Swap(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
泛型接口
interface IMonth { }
interface IJanuary : IMonth { } //No error
interface IFebruary : IMonth { } //No error
interface IMarch : IMonth { } //No error
r
泛型委托
int[] arr = new int[3];
Array:
Array 类是 C# 中所有数组的基类。Array类是一个抽象类,所以不能使用构造函数来创建数组.
可以通过调用Array.CreateInstance
动态创建一个数组实例。该方法可以在运行时指定元素类型、维数,以及通过指定数组下界来实现非零开始的数组。GetValue
和SetValue
方法可用于访问动态创建的数组元素(访问普通数组元素亦可)
Array a = Array.CreateInstance(typeof(string), 2);
a.SetValue("hi", 0); // → a[0] = "hi";
a.SetValue("there", 1); // → a[1] = "there";
string s = (string)a.GetValue(0); // → s = a[0];
其他用途是:调用Array 类的方法,如
int[] list = { 34, 72, 13, 44, 25, 30, 10 };
Array.Sort(list);
Array.Reverse(list);
数组的遍历:foreach
int ncout = 0;
int[] arr = { 34, 72, 13, 44, 25, 30, 10 };
foreach(var nvalue in arr)
{
ncout += nvalue;
}
元组
元组用静态Tuple类的静态create方法创建
Tuple tt = Tuple.Create(1, "hello");
is运算符
class CWorkbase
{
}
class CWorkchild : CWorkbase
{
public int a;
}
CWorkchild ch = new CWorkchild();
ch.a = 2;
if (ch is CWorkbase)
{
int asa = 1;
}
CWorkbase base11 = ch as CWorkbase;
if (base11 != null)
{
int ss = 1;
}
都可以通过可视化的方式设置,先自定义后触发事件的函数,然后在可视化属性中设置。
键盘
C#中描述"KeyDown"、"KeyUp"的事件的Delegate是"KeyEventHandler"。而描述"KeyPress"所用的Delegate是"KeyPressEventHandler"。这二个Delegate都被封装在命名空间"Syetem.Windows.Froms"中。为"KeyDown"、"KeyUp"的事件提供数据的类是"KeyEventArgs"。而为"KeyPress"事件提供数据的类是"KeyPressEventArgs"。同样这二者也被封装在命名空间"Syetem.Windows.Froms"中。
一般来说,在键盘按下某个按键,事件处理步骤为:keydown-> keypress -> keyup .若按下的是控制键,则触发的事件过程为keydown -> keyup.
button1. KeyUp += new Syetem.Windows.Froms. KeyEventHandler(button1_KUp);
private void button1_KUp ( object sender , Syetem.Windows.Froms. KeyEventArgs e )
{
此处加入响应此事件的代码
}
button1. KeyPress += new Syetem.Windows.Froms. KeyPressEventArgs(button1_KPress);
private void button1_KPress ( object sender , Syetem.Windows.Froms. KeyPressEventArgs e )
{
此处加入响应此事件的代码
}
鼠标:
将鼠标指针移向控件时会触发MouseEnter事件,在控件上移动鼠标会不断触发mosemove事件,鼠标指针停驻在控件上不动会触发mousehover事件,在控件上单击鼠标按键或者滚动鼠标滚轮会触发mousedown和mousewheel事件,放开鼠标时会触发mouseup事件,离开控件时则触发mouseleave事件。
单击控件,所触发的事件如下:
1.mousedown事件
2.click
3.mouseclick
4.mouseup
在C#中是通过不同的Delegate来描述上述事件,其中描述"MouseHover"、"MouseLeave"、"MouseEnter"事件的Delegate是"EventHandler",而描述后面的三个事件的Delegate是"MouseEventHandler"来描述。这二个Delegate分别被封装在不同的命名空间,其中"EventHandler"被封装在"System"命名空间;"MouseEventHandler"被封装在"Syetem.Windows.Froms"命名空间中的。在为"MouseHover"、"MouseLeave"、"MouseEnter"事件通过数据的类是"EventArgs",他也被封装在"System"命名空间中;而为后面的三个事件提供数据的类是"MouseEventArgs",他却被封装在"Syetem.Windows.Froms"命名空间。
如
button1.MouseLeave += new Syetem.EvenHandler(button1_MLeave);
private void button1_MLeave ( object sender , System.EventArgs e )
{
此处加入响应此事件的代码
}
button1.MouseMove += new System.Windows.Forms.MouseEventHandler(button1_MMove);
private void button1_MMove ( object sender , System.Windows.Forms. MouseEventArgs e )
{
此处加入响应此事件的代码
}