消歧义,指向类里的成员
现在要求你编写一个程序,在一个"计算器"类里,设定一个int字段并赋值2.再写一个方法,带有一个int参数,返回这个参数和int字段相乘的值,并且要求参数名与字段名相同.
然后就写出这样一个程序
你可能也会诧异,这什么跟什么,到底是什么number乘什么number?
然后我们就可以正式介绍this关键字.在return number*number;的第一个number前面加上this.,变成return this.number * number;.鼠标点到this.上,会惊奇的发现this.number指向了类里的字段.
于是程序就可以正常运行了
using System;
namespace CSharplearn
{
class 计算器
{
int number = 2;
public int mul(int number)
{
return this.number * number;
}
}
class Program
{
static void Main(string[] args)
{
计算器 a = new 计算器();
Console.WriteLine(a.mul(3));
}
}
}
结果:
在未来的编程,一个不经意就会写出重名的变量,此时可以使用this来消歧义.
常见用法:
使用构造函数给类里的字段传递值.字段就可以使用internal等修饰符来保护起来.
然而这只是this的其中一种用法而已
传引用
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter06.Listing06_12
{
// In a completed Employee implementation FirstName, LastName
// and salary would be accessed
public class Employee
{
public string FirstName;
public string LastName;
public string Salary;
public void Save()
{
DataStorage.Store(this);
}
}
class DataStorage
{
// Save an employee object to a file
// named with the Employee name
public static void Store(Employee employee)
{
// ...
}
}
}
DataStorage类下有个Store()方法,Store方法是用来存Employee类的成员的,参数也是Employee类的.但是现在我想在Employee下定义一个方法,这个方法的作用是能保存Employee类里的数据.DataStorage类里已经有一个储存方法了,于是就借用了DataStorage.Store.问题是这个方法的参数该怎么传,this就能解决这个问题,this指向的是Employee类.
让我们理清楚在使用Employee.Save()后发生了什么.Employee.Save()调用了DataStorage.Store(),传递的参数其实就是这个对象,我拿到了这个对象可以干很多事情比如我存储对象里的字段并打印…
下面是C#本质论6.12和6.13结合起来再稍微加了一点修改的代码
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter06.Listing06_12
{
// In a completed Employee implementation FirstName, LastName
// and salary would be accessed
using System.IO;
public class Employee
{
public string FirstName;
public string LastName;
public string Salary;
public void Save()
{
DataStorage.Store(this);
}
}
public class DataStorage
{
// Save an employee object to a file
// named with the Employee name
// Error handling not shown
public static void Store(Employee employee)
{
// Instantiate a FileStream using FirstNameLastName.dat
// for the filename. FileMode.Create will force
// a new file to be created or override an
// existing file
FileStream stream = new FileStream(
employee.FirstName + employee.LastName + ".dat",
FileMode.Create);
// Create a StreamWriter object for writing text
// into the FileStream
StreamWriter writer = new StreamWriter(stream);
// Write all the data associated with the employee
writer.WriteLine(employee.FirstName);
System.Console.WriteLine(employee.FirstName);
writer.WriteLine(employee.LastName);
System.Console.WriteLine(employee.LastName);
writer.WriteLine(employee.Salary);
System.Console.WriteLine(employee.Salary);
// Dispose the StreamWriter and its stream
writer.Dispose(); // Automatically closes the stream
}
// ...
}
class Program
{
static void Main(string[] args)
{
Employee employee = new Employee() { FirstName = "xalloy",LastName = "machine",Salary = "medium"};
employee.Save();
}
}
}
结果:
我在实例化Employee的时候初始化了类里的三个字段,然后使用了employee.Save().由于DataStorage.Store()没有写完全,所以不能实际创建文件并写入.但为了测试该方法是否真的接受到了实例,我在里面加了三个打印方法,结果是接收到了.
扩展方法
C#的源代码已经被封闭住了,但是有些时候我们仍然希望自己能加方法到某个类进去.例如,我string a;但是我们返回这个字符串变成int就要int.Pars(a);为什么非要这么麻烦,我就不能直接a.ToInt()就把他转换成int类型嘛?问题是String类里根本没有这个方法,那怎么办?
我们可以自己在外部写一ToInt个方法,来扩展已有的String类,这就是扩展方法.
怎么写这个扩展方法?首先我们要创建一个新文件,然后我们要写一个静态类,再在这个类里写一个静态方法,这个静态方法就是我们要扩展的方法,最后在方法里的参数写上this,this后面空格加我们要扩展的类
文件一 ExtentedMethod.cs
using System;
static class ExtentedMethod
{
public static int ToInt(this String a)
{
return int.Parse(a);
}
}
我们扩展的方法还是执行了int.Parse()
using System;
namespace CSharplearn
{
class Program
{
static void Main(string[] args)
{
string a = "123456";
var b = a.ToInt();
Console.WriteLine(b+6);
}
}
}
但是用法却不一样了,变成了我们扩展的ToInt方法
结果:
base关键字
base关键字与this关键字有异曲同工之处.
using System;
namespace CSharplearn
{
class 计算器
{
public int number = 3;
public int Mul(int number)
{
return this.number * number;
}
}
class 计算器二 : 计算器
{
public new int number;
public int Div(int number)
{
return base.number / number;
}
}
class Program
{
static void Main(string[] args)
{
计算器 a = new 计算器{ number = 2};
Console.WriteLine(a.Mul(3));
计算器二 b = new 计算器二();
Console.WriteLine(b.Div(1));
}
}
}
结果:
这串代码与上串代码的区别在于,多了一个继承于"计算机"类的"计算器二"类,里面有一个除法方法.这个除法方法也有两个number,区别在于一个有base一个没有.
base关键字用于从派生类中访问基类的成员.怎么理解?把鼠标点上去就知道了.
可以看到加了base关键词的number指向了父类的number.所以这里的base.number其实就是父类的number字段.