1、构造方法
构造方法可以为对象的属性赋值,如果自己不定义构造方法,则会提供一个默认的无参数的构造方法。自己可以在类中定义构造方法,构造方法名字和类名相同,写法基本和函数相同,只是不写返回值类型,也无需返回值。构造方法通常为public。调用构造方法只能使用new关键字进行调用。构造方法也支持重载。例:
public class Child
{
int age;
string name;
public Child()
{
age = 12;
name = "HelloWorld";
}
//根据参数实例化对象
public Child(int ageTemp,string nameTemp)
{
age = ageTemp;
name = nameTemp;
}
}
Child xiaoming = new Child();//调用自己写的无参构造方法
Child xiaohua = new Child(15,"xiaohua");//调用自己重载的有参构造方法
2、对象初始化器
在对象初始化时,可以使用对象初始化器来简化写法。使用初始化器时可以省略类名后面的圆括号。例:
public class Child
{
int age;
string name;
public Child(int age,string name)
{
this.age = age;//通过this关键字访问到类的age,并将形参age的值赋给类里的age
this.name = name;
}
}
//使用无参的构造方法,然后依次赋值,这种写法稍微麻烦点
Child xiaohua = new Child();
xiaohua.age = 12;
xiaohua.name = "xiaohua";
Child xiaoming = new Child{age = 23,name = "xiaoming"};//使用对象初始化器初始化,简洁一些,类似于C语言的结构体的赋值
Child xiaohua= new Child(){age = 23,name = "xiaohua"};
3、C#值类型与引用类型。
值类型:int、bool、char、float、double… 引用类型:类(string也是类)、数组、接口。
值类型变量存储的是值,在赋值的时候会创建值的副本,当自身修改时并不会影响前面被赋值的变量。
引用类型变量存储的是对象的内存地址,赋值的时候会创建地址的副本,当自身修改时前面被赋值的变量还是指向了自身,故值也会被改变。(参照C语言指针操作)
Child c1 = new Child();
c1.age = 12;
Child c2 = c1;
c2.age = 10;
//此时c1和c2的年龄都是10,因为类是引用类型
4、C#结构体。
结构体与类的操作基本相同,不同的是:结构是值类型,而类是引用类型;结构中不允许为字段赋初值;结构中不允许定义无参的构造方法,且有参的构造方法需要在内部为所有字段赋值;结构类型的变量可以不实例化。
5、ref与out关键字的使用
ref关键字可以让值类型的变量在方法参数传递时按照引用类型传递。即在方法里面修改值,方法外的那个实参也会被修改。需要注意的是,在调用方法的时候需要在变量名前面加上ref关键字说明一下,在定义方法时,也需要在形参的数据类型前面加上ref关键字;同时要注意的是,使用ref传递的参数必须有初值才行。
out关键字也可以让值类型的数据在传递的时候按照引用类型传递,不同于ref的是,out关键字主要是用来获取一个结果,ref是为了传参。当我们的方法需要返回多个返回值时,我们可以使用out关键字用来获取想要返回的结果,然后在方法内部对其进行赋值。在调用的时候同样需要加上out关键字标明,在调用前对值没有要求。
ref使用案例:
public class Child
{
public int age = 9;
}
class Program
{
static void Main(string[] args)
{
int age = 3;
Child xiaoming = new Child();
Console.WriteLine("我今年{0}岁了!",age);
Console.WriteLine("小明今年{0}岁了!",xiaoming.age);
Add(ref age);
Add(ref xiaoming.age);//参数为类的字段也可以
Console.WriteLine("我今年{0}岁了!",age);
Console.WriteLine("小明今年{0}岁了!",xiaoming.age);
Console.ReadKey();
}
static public void Add(ref int age)
{
age++;
Console.WriteLine("长大一岁了!");
}
}
out使用案例:
class Program
{
static void Main(string[] args)
{
//使用out关键字可以让方法返回多个值
int td, yd = 9;
GetData(out td,out yd);
Console.WriteLine("昨天是{0}号,今天是{1}号。",yd,td);
Console.ReadKey();
}
static public void GetData(out int td,out int yd)
{
//方法内部必须为其赋值
td = 13;
yd = 12;
}
}
6、泛型类
泛型类可以根据传入的参数类型来生成该类型的类,其类似于C语言中的typedef,在编写泛型类时仅需使用一个非关键字的东西占位即可,而具体使用时再传入参数,就可以得到一个将占位的东西全部修改为对应类型的类了。写法:普通类名。这里的T可以换成其他的名字
定义一个狗的类和猫的类,再定义一个泛型的笼子类,这样传入猫类则得到了一个猫的笼子,而传入狗的类则得到了一个狗的类。例:
public class Dog
{
public string name;
public int age = 0;
public Dog(string name)
{
this.name = name;
}
}
public class Cat
{
private string name;
public int age = 0;
public Cat(string name)
{
this.name = name;
}
public string Name
{
set { name = value; }
get { return name; }
}
}
public class Cage<T>
{
T[] array;
readonly int SIZE;
public int num;
public Cage(int n)
{
SIZE = n;
num = 0;
array = new T[SIZE];//实例化数组
}
//放入一个动物
public void Push(T t)
{
if (num < SIZE)
{
array[num++] = t;
}
else
{
Console.WriteLine("Cage is full");
}
}
public T Pop()
{
if (num > 0)//如果还有动物
{
return array[--num];
}
else
{
Console.WriteLine("The Cage is Empty!");
return default(T);//返回一个默认的T
}
}
}
class Program
{
static void Main(string[] args)
{
var dogCage = new Cage<Dog>(1);
dogCage.Push(new Dog("A"));
dogCage.Push(new Dog("B"));
var dog = dogCage.Pop();
Console.WriteLine("name is :"+dog.name);
dog = dogCage.Pop();
var catCage = new Cage<Cat>(3);
catCage.Push(new Cat("A"));
catCage.Push(new Cat("B"));
for (int i = 0; i <= catCage.num; i++)
{
var cat = catCage.Pop();
Console.WriteLine("Cat name is "+cat.Name);
}
Console.ReadKey();
}
}