在本章节内容,主要关于类的细节处理和结构体一点点介绍。
2.1 类和结构
类和结构体实际上都是创建对象的模板,每个对象都有包含数据,并提供了处理和访问的方法。类和结构体得区别是他们在内存的存储方式上的引用,类是存储在堆上的引用类型,而机构体是存储在堆栈上的值类型。在较小的数据类型使用结构可以提高性能,但在语法上和类很相似。主要区别在于是使用关键字struct代替class来声明结构体。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
string firstName;
string lastName;
}
2.2 ref参数
ref参数,是指类中一般方法的ref参数。如果一个方法的参数前带有ref关键字,则该方法对变量所作的任何改变 都会影响到原来对象的值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Collections.Generic;
namespace CSharpDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(TimeOfDay.Moring);
int i = 20;
doSomeThing(ref i);
Console.WriteLine(i.ToString());
}
public enum TimeOfDay
{
Moring=0,
AfterNoon=1,
Evening=2
}
static void doSomeThing(ref int i)
{
i = i + 100;
}
}
}
注意事项:在传递给方法前,无论是值传递,还是引用传递,变量都需要初始化。
2.3 out 关键字
在方法的输入参数前面加了out关键字时,传递给对方的变量可以不初始化。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Collections.Generic;
namespace CSharpDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(TimeOfDay.Moring);
int i;
doSomeThing(out i);
Console.WriteLine(i.ToString());
}
public enum TimeOfDay
{
Moring=0,
AfterNoon=1,
Evening=2
}
static void doSomeThing(out int i)
{
i = 100;
}
}
}
out和ref区别:
ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。
使用ref前必须对变量赋值,out不用。
out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。
2.4 方法重载
方法重载只需声明同名但参数个数或者类型不同的方法即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public void doSomeThing(int i)
{
i = 100;
}
//方法重载
public void doSomeThing(string i)
{
i = "111";
}
注意事项:
1.C#重载不支持可选参数
2.重载不能仅在返回类型上有所区别
3.重载不能仅根据参数声明为ref还是out区别
2.5 只读字段readonly
readyonly关键字比const灵活的多,允许把一个字段设置为常量,但可以执行一些运算,来确定其初始值,其规则是可以在构造函数中给只读字段赋值,但不能在其他地方赋值。若要设置只读字段为静态,那么必须设置显式声明。
2.6 部分类 partial关键字
partial关键字允许把类、结构体或接口放在多个文件中。一般类存储在一个文件中。但有时候多个开发人员需要访问同一个类,或者某种类型的代码生成器生成了一个类某部分,所以把类放在多个文件时有益的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
partial class demo1
{
public void method1()
{
}
}
//demo1.cs
partial class demo1
{
public void method2()
{
}
}
2.7 静态类
静态类使用可以不创建实例化,就可以调静态类中的方法。如下示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Collections.Generic;
namespace CSharpDemo
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine(TimeOfDay.Moring);
//int i;
//doSomeThing(out i);
//Console.WriteLine(i.ToString());
StaticClass.helpMe();
}
}
public static class StaticClass
{
public static void helpMe()
{
Console.WriteLine("help");
}
}
}
2.8 扩展方法
有许多方法扩展类。如果有类的源代码,继承就是给对象添加功能的好方法,但是若果没有源代码怎么办呢,这个时候我们就可以使用扩展方法啦。它允许改变一个类,但不需要改变源代码。扩展方法是静态方法,是类的一部分,但实际上没有放在类得源代码中。
假如一个money类需要一个方法AddToAmount(decimal amountToAdd)。但是我不修改源代码,此时创建一个静态类,把方法AddToAmount添加为一个静态方法,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace Wrox.ProCSharp.OOCSharp
{
class MainEntryPoint
{
static void Main(string[] args)
{
Money cash1 = new Money();
cash1.Amount = 40M;
Console.WriteLine("cash1.ToString() returns: " + cash1.ToString());
//Extension Method
cash1.AddToAmount(10M);
Console.WriteLine("cash1.ToString() returns: " + cash1.ToString());
Console.ReadLine();
}
}
class Money
{
private decimal amount;
public decimal Amount
{
get
{
return amount;
}
set
{
amount = value;
}
}
public override string ToString()
{
return "$" + Amount.ToString();
}
}
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
public static class MoneyExtension
{
public static void AddToAmount(this Money money, decimal amountToAdd)
{
money.Amount += amountToAdd;
}
}
}
说明:调用扩展方法使用.cash1.AddToAmount(18M);