一:类和结构
类和结构实际上都是对象的模板,每个对象都包含数据,并且提供了处理和访问数据的方法,类定义了每个对象(称为实例)可以包含什么数据和功能。
class MyClass
{
public const string DayOfSendingBill = "Monday";
public int CustomerID;
public string FirstName;
public string LastName;
}
结构和类的区别:
在于他们的存储方式,访问方式(类是存储在堆上面的(heap)上的引用类型,而结构是存储在栈上面的值类型)和他们的一些特征(比如结构不支持继承),较小的数据类型使用结构可以提高性能
struct myStruct
{
public const string DayOfSendingBill = "Monday";
public int CustomerID;
public string FirstName;
public string LastName;
}
结构和类的初始化:
myStruct myStruct = new myStruct();
MyClass MyClass = new MyClass();
二.类
类中的数据和函数称为类的成员
数据成员
数据成员是包含类的数据–字段,常量和事件的成员,数据成员可以使静态数据。类的成员总是实例成员,除非用static进行显示的声明
字段是与类相关的变量。
ps:静态与非静态的区别
*静态类是不能实例化的,我们直接使用它的属性与方法,静态类最大的特点就是共享。
静态类中的所有成员必须是静态的。
静态类可以有静态构造函数,静态构造函数不可继承。搜索
静态构造函数可以用于静态类,也可用于非静态类。
静态构造函数无访问修饰符、无参数,只有一个 static 标志。
静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数被自动执行,并且只执行一次。非静态类需要你自己去实例化加载它,才能调用
C#静态方法与非静态方法比较一、
C#静态成员:
①静态成员属于类所有,非静态成员属于类的实例所有。
②每创建一个类的实例,都会在内存中为非静态成员新分配一块存储;
静态成员属于类所有,为各个类的实例所公用,无论类创建了多少实例,类的静态成员在内存中只占同一块区域。
C#静态方法与非静态方法比较二、
C#静态方法
1、C#静态方法属于类所有,类实例化前即可使用。
2、非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员。
3、因为静态方法在类实例化前就可以使用,而类中的非静态变量必须在实例化之后才能分配内存,
这样,C#静态方法调用时无法判断非静态变量使用的内存地址。所以无法使用。而静态变量的地址对类来说是固定的,故可以使用。
C#静态方法与非静态方法比较三、
C#静态方法是一种特殊的成员方法 它不属于类的某一个具体的实例,而是属于类本身。所以对静态方法不需要首先创建一个类的实例,而是采用类名.静态方法的格式 。
1.static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用!
static内部只能出现static变量和其他static方法!而且static方法中还不能使用this….等关键字..因为它是属于整个类!
2.静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。
3.静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存.
4.C#中的方法有两种:实例方法,静态方法.
C#静态方法与非静态方法比较四、
C#静态方法中获取类的名称
静态方法中用:
string className = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;
非静态方法中还可以用:
string className = this.GetType().FullName;
常量与类的关联方式和变量与类的关联方式相同,使用const关键字来声明常量,如果是public,那么就可以在类的外部访问它。
事件是类的成员,在某些行为发生时,可以让对象通知调用方,客户可以包含所谓“事件处理程序”的代码来响应事件。
函数成员
函数成员提供了操作类中数据的某些功能,包括方法,属性,构造函数和终结器,运算符以及索引器。
1.方法与某个类的相关函数,与数据成员一样,函数成员默认为实例成员,使用static修饰符可以把方法定义为静态方法。
2.属性是可以从客户端访问的函数组其访问方式与访问类的公共字段类似。
3.构造函数是在实例化对象时候字段调用的特殊函数,他们必须和类名相同,并且不能有返回类型,构造函数用于初始化字段的值
4.终结器类似于构造函数,但是在CLR检测到不再需要某个对象的时候调用它。他的名称和类相同,但是前面有一个“~”符号。
5.运算符执行的最简单的操作是加法和减法,c#还允许运算符重载。
6.索引器允许对象以数组或集合的方式进行索引。
ps:c#只有字段,常量和事件才是数据成员。
方法:
方法的声明:
private int lovejing(int year)
{
return year;
}
调用方法:
static void Main(string[] args)
{
myStruct myStruct = new myStruct();
MyClass myClass = new MyClass();
int id = MyClass.DoubleID(10);
myClass.FirstName = "li";
myClass.LastName = "xiongwen";
string name = myClass.GetName();
double pi = MyClass.GetPI();
Console.WriteLine("id=" + id.ToString() + "name=" + name + "pi=" + pi.ToString());
Console.ReadKey();
}
class MyClass
{
public const string DayOfSendingBill = "Monday";
public int CustomerID;
public string FirstName;
public string LastName;
public string GetName()
{
return FirstName + LastName;
}
public static int DoubleID(int x)
{
return x * 2;
}
public static double GetPI()
{
return 3.1415926;
}
}
给方法传递参数:
ref参数:
如果把一个参数传递给方法,而且这个方法的输入参数前面带有ref关键字,则该方法对变量所做的任何改变都会影响原始对象的值。
static void Main(string[] args)
{
int[] xiong = new int[1];
xiong[0] = 30;
int a = 20;
SomeFunction(xiong, ref a);
Console.WriteLine(xiong[0].ToString() + "a=" + a.ToString());
Console.ReadKey();
}
static void SomeFunction(int[] ints,ref int i)
{
ints[0] = 100;
i = 100;
}
out 参数:
在方法的输入参数前面加上out前缀时,传递给该方法的变量可以不初始化,改变量通过引用传递,所以在从被调用的方法中返回时,对应方法对改变量进行的任何改变都会保留下来,在调用改方法时,也需要使用out关键字。
static void Main(string[] args)
{
int a;
SomeFunctionTO(out a);
Console.WriteLine(a.ToString());
Console.ReadKey();
}
static void SomeFunctionTO(out int i )
{
i = 100;
}
命名参数:
可选参数:要是这个方法正常工作,就必须在最后定义optionalNumber参数
方法的重载:
c#支持方法的重载–方法的几个不同的版本(方法名相同,但是参数的个数或者类型不同)。
class ResultDisplayer
{
void DisplayResult(string result)
{
Console.WriteLine(result);
}
void DisplayResult(int result)
{
Console.WriteLine(result);
}
void DisplayResult(int result,string am)
{
Console.WriteLine(result);
}
}
c#在重载方法的参数方面有一些小限制即可:
两个方法不能仅在返回类型上有区别
两个方法不能仅仅根据参数是ref还是out来区分
属性访问器:
private int customerID;
public int CustomerID
{
get
{
return customerID;
}
set
{
customerID = value;
}
}
我们可以公开这个参数的读写属性,也可以让他只能读或者只能写。c#也支持给属性访问器设置访问修饰符。
构造函数
构造函数声明和类名一样,但是没有返回值
class MyClass
{
public string LastName;
public MyClass()
{
}
public MyClass(int a)
{
customerID = a;
}
}
1.如果提供了带参的构造函数,那么编译器就不会自动提供默认的构造函数,如果构造函数有参数,那么,我们在初始化类的时候就需要传入参数。
MyClass myClass = new MyClass(10);
2.我们可以吧构造函数定义为private或者protected
类仅用作某些静态成员或属性的容器,因此永远不会实例化它
希望类仅通过调用某个静态成员函数来实例化(这就是所谓对象实例化的类工厂方法)
静态构造函数:
c#一个新特征是也可以给类编写无参数的静态构造函数,这种构造函数值执行一次,而前面的构造函数是实例化构造函数,只要创建类的对象,就会执行它。静态构造函数只能访问类的静态成员,不能访问类的实例成员!
无参构造函数和静态构造函数不会冲突,加载类时执行静态构造函数,创建实例时执行实例构造函数
只读字段:
readonly
匿名类型:
var
三.结构
struct Dimesions
{
public double Length;
public double Width;
public Dimesions(double length,double width)
{
Length = length;
Width = width;
}
public double Diagonal
{
get
{
return Math.Sqrt(Length * Length + Width * Width);
}
}
}
结构是值类型,不是引用类型,他们存储在栈中。
1.结构不支持继承
2.构造函数的工作方式有一些区别,尤其是编译器总会提供一个午餐的构造函数,他是不允许替换的
3.使用结构,可以指定字段如何在内存中布局
结构是值类型:
因为结构是值类型,所以new 运算符与类和其他的引用类型的工作方式不一样,new运算符并不在堆中分配内存,而只是调用相应的构造函数,根据传给他的参数初始化所有的字段,结构是会影响性能的值类型。
结构和继承:
结构不支持继承
结构的构造函数:
结构中不能付初始值,但是类可以
弱引用
静态类
Object类