引言
最近有接触到 C# 静态方法中 this
做为参数紧跟类名,实现对类的扩展。觉得很好奇,便想了解一下 C# 中 this 关键字的用法,主要有 5 类用法。
内容提要:
- 限定类似名称隐藏的成员
- 将对象作为参数传递给方法
- 声明索引器
- 串联构造函数
- 扩展方法
限定类似名称隐藏的成员
用 this
区别类成员和参数
public class Employee
{
private string alias;
private string name;
public Employee(string name, string alias)
{
// Use this to qualify the members of the class
// instead of the constructor parameters.
this.name = name;
this.alias = alias;
}
}
将对象作为参数传递给方法
Tax.CalcTax(this)
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;
// Constructor:
public Employee(string name, string alias)
{
// Use this to qualify the fields, name and alias:
this.name = name;
this.alias = alias;
}
// Printing method:
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}
public decimal Salary
{
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}
class MainClass
{
static void Main()
{
// Create objects:
Employee E1 = new Employee("Mingda Pan", "mpan");
// Display results:
E1.printEmployee();
}
}
/*
Output:
Name: Mingda Pan
Alias: mpan
Taxes: $240.00
*/
声明索引器
索引器类似于属性。 很多时候,创建索引器与创建属性所使用的编程语言特性是一样的。 索引器使属性可以被索引:使用一个或多个参数引用的属性。 这些参数为某些值集合提供索引。
使用 this
关键字作为属性名声明索引器,并在方括号内声明参数。
namespace ConsoleApp1
{
public class IndexExample
{
private string[] nameList = new string[10];
public string this[int index]
{
get { return nameList[index]; }
set { nameList[index] = value; }
}
public int this[string name]
{
get
{
for(int i = 0; i < nameList.Length; i++)
{
if(nameList[i] == name) return i;
}
return -1;
}
}
}
public class Program
{
public static void Main(string[] args)
{
IndexExample indexExample = new IndexExample();
indexExample[0] = "Tom";
indexExample[1] = "Lydia";
Console.WriteLine("indexExample[0]: " + indexExample[0]);
Console.WriteLine("indexExample['Lydia']: "+ indexExample["Lydia"]);
}
}
}
输出:
indexExample[0]: Tom
indexExample['Lydia']: 1
串联构造函数
用 this
调用构造函数
namespace ConsoleApp1
{
public class Test
{
public Test()
{
Console.WriteLine("no parameter");
}
public Test(string str) : this()
{
Console.WriteLine("one parameter: " + str);
}
public Test(string str1, string str2): this(str1)
{
Console.WriteLine("two parameters: " + str1 + " ; " + str2);
}
}
public class ProgramTest
{
static void Main(string[] args)
{
Console.WriteLine("Test t1 = new Test();");
Test t1 = new Test();
Console.WriteLine("Test t2 = new Test('str1');");
Test t2 = new Test("str1");
Console.WriteLine("Test t3 = new Test('str2', 'str3');");
Test t3 = new Test("str2", "str3");
}
}
}
输出:
Test t1 = new Test();
no parameter
Test t2 = new Test('str1');
no parameter
one parameter: str1
Test t3 = new Test('str2', 'str3');
no parameter
one parameter: str2
two parameters: str2 ; str3
扩展方法
- 定义包含扩展方法的类必须为
静态类
- 将扩展方法实现为
静态方法
,并且使其可见性至少与所在类的可见性相同。 - 此方法的
第一个参数指定方法所操作的类型
;此参数前面必须加上this
修饰符。 - 在调用代码中,添加
using
指令,用于指定包含扩展方法类的using
。 - 和调用类型的实例方法那样调用这些方法。
以下示例实现 CustomExtensions.StringExtension 类中名为 WordCount 的扩展方法。 此方法对 String
类进行操作,该类指定为第一个方法参数。 将 CustomExtensions 命名空间导入应用程序命名空间,并在 Main 方法内部调用此方法。
using System.Linq;
using System.Text;
using System;
namespace CustomExtensions
{
// Extension methods must be defined in a static class.
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static int WordCount(this string str)
{
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
namespace Extension_Methods_Simple
{
// Import the extension method namespace.
using CustomExtensions;
class Program
{
static void Main(string[] args)
{
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine("Word count of s is {0}", i);
}
}
}
同样,我们也可以扩展任意自定义类。
Test 类:
namespace ConsoleApp1
{
public class Test
{
public Test()
{
Console.WriteLine("constructor method");
}
public void myMethod()
{
Console.WriteLine("this is MyMethod");
}
}
}
Test 扩展类,定义了一个扩展方法:
namespace ConsoleApp1.ExtendMethod
{
public static class TestExtend
{
public static void ExtendMethod(this Test t)
{
Console.WriteLine("this is extention method");
}
}
}
测试一下:扩展方法就跟自己的方法一样,可以调用。
using ConsoleApp1.ExtendMethod;
namespace ConsoleApp1.Execution
{
public class ProgramTest
{
static void Main(string[] args)
{
Test t1 = new Test();
t1.myMethod();
t1.ExtendMethod();
}
}
}
输出:
constructor method
this is MyMethod
this is extention method