访问修饰符是用于指定成员或类型的声明可访问性
的关键字。
● public(公共的)
● protected(受保护的)
● internal(内部的)
● private(私有的)
● public 访问不受限制
● protected 访问限于包含类或派生自包含类的类型
● internal 访问限于当前程序集
● private 访问限于包含类
● protected internal 访问限于当前程序集或派生自包含类的类型访问
● private protected 访问限于包含类或当前程序集中包含类的派生类的类型访问
Internal
public 或 internal
private
public、internal 或 private 注意:结构成员无法声明为 protected、protected internal 或 private protected,因为结构不支持继承。
public、protected internal、protected、internal、private protected 或 private
readonly
关键字(运行时常量):字段可以在声明或构造函数中初始化,常作为运行时常量使用。
const
关键字(编译时常量):字段只能在该字段的声明时初始化,常作为编译时常量使用过。
从 C# 10 开始,如果所使用的所有表达式也是常量字符串,则内插字符串可以是常量。 此功能可以改进生成常量字符串的代码:
const string Language = "C#";
const string Platform = ".NET";
const string Version = "10.0";
const string FullProductName = $"{Platform} - Language: {Language} Version: {Version}";
readonly 关键字与 const 关键字不同。 const 字段只能在该字段的声明中初始化。 字段可以在声明或构造函数中初始化。 因此,根据所使用的构造函数,readonly 字段可能具有不同的值。 另外,虽然 const 字段是编译时常量,但 readonly 字段可用于运行时常量,如此行所示:public static readonly uint l1 = (uint)DateTime.Now.Ticks;
virtual
关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写(使用override关键字对虚方法重写)。 例子:
class Person{
public virtual void func(){ Console.WriteLine("Person-- func") }
public virtual void foo(){ Console.WriteLine("Person-- foo") }
}
class Student{
//重写Person类中的虚方法
public override void func(){ Console.WriteLine("Student-- func") }
public override void foo(){ Console.WriteLine("Student-- foo") }
}
作用:扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现需要 override 修饰符
作用:使用 static 修饰符可声明属于类型本身而不是属于特定对象的静态成员。 static 修饰符可用于声明 static 类。 在类、接口和结构中,可以将 static 修饰符添加到字段、方法、属性、运算符、事件和构造函数。 static 修饰符不能用于索引器或终结器。
Number | Description |
---|---|
1 | 静态类无法实例化(换句话说,无法使用 new 运算符创建类类型的变量。 由于不存在任何实例变量,因此可以使用类名本身访问静态类的成员)。 |
2 | 静态构造函数只调用一次,在程序所驻留的应用程序域的生存期内,静态类会保留在内存中(即使用Static修饰的类,应用一旦启用静态类就会保留在内存中) |
3 | 静态类只包含静态成员 |
4 | 不能包含实例构造函数 |
5 | 静态类会进行密封,因此不能继承。 它们不能继承自任何类(除了 Object)。 静态类不能包含实例构造函数。 但是,它们可以包含静态构造函数 |
代码示例: |
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
ToolsHelper.SayHello();
}
}
static class ToolsHelper
{
//静态类只包含静态成员
//private string name = "rickey.gong";
//不能包含实例构造函数
//public void ToolsHelper()
//{
//}
//可以包含静态构造函数
static ToolsHelper()
{
Console.WriteLine("静态类 -- 静态构造方法");
}
internal static void SayHello()
{
Console.WriteLine("静态类 -- SayHello方法");
}
}
}
打印结果:
静态类 – 静态构造方法
静态类 – SayHello方法
成员主要指的是:字段、方法、属性、运算符、事件和构造函数等。
优点 | 缺点 |
---|---|
属于类级别的,不需要创建对象就可以直接使用 | 静态方法不能调用非静态的方法和变量。(非静态方法可以任意的调用静态方法/变量) |
全局唯一,内存中唯一,静态变量可以唯一标识某些状态 | 不可以使用 this 引用 static 方法或属性访问器 |
在类加载时候初始化,常驻在内存中,调用快捷方便 |
序号 | 描述 |
---|---|
1 | 异步方法,通过使用 async 修饰符定义 |
2 | 迭代器方法,包括 yield return 或 yield break 语句 |
3 | 扩展方法的第一个参数不能有 in 修饰符,除非该参数是结构 |
4 | 扩展方法的第一个参数,其中该参数是泛型类型(即使该类型被约束为结构) |
ref | out |
---|---|
指定此参数由引用传递,指定的参数在函数调用时必须先初始化(有进有出) |
指定此参数由引用传递,指定的参数在进入函数时会清空参数值,因此该参数必须在调用函数内部进行初始化赋值操作(无进有出) |
as | is |
---|---|
只是做类型兼容判断,并不执行真正的类型转换。返回true或false,不会返回null,对象为null也会返回false | as运算符将表达式结果显式转换为给定的引用类型或可以为null值的类型。 如果无法进行转换,则as运算符返回 null |
总结:as模式的效率要比is模式的高,因为借助is进行类型转换的化,需要执行两次类型兼容检查。而as只需要做一次类型兼容,一次null检查,null检查要比类型兼容检查快。
上代码:
is
public class Person
{
string Name { get; set; }
int Age { get; set; }
public void SayHello() { Console.WriteLine("Person -- SayHello"); }
}
public class Student : Person
{
public void WriteHomeWork()
{
Console.WriteLine("Student -- WriteHomeWork");
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
Student s = new Student();
object b = new Person();
Console.WriteLine(b is Person);//true
Console.WriteLine(b is Student);//false
Console.WriteLine(p is Student);//false
Console.WriteLine(s is Person);//true
//应用
if (s is Person)
{
p = new Student();
Console.WriteLine("类型转换成功");
}
else
{
Console.WriteLine("类型转换失败");
}
}
}
as
public class Person { }
public class Student : Person { }
class Program
{
static void Main(string[] args)
{
Student s = new Student();
Person p = s as Person;
if (p == null)
{
Console.WriteLine("类型转换失败");
}
else
{
Console.WriteLine("类型转换成功");
}
}
}
结束整个方法,return关键字并不是专门用于跳出循环的,return的功能是结束一个方法。 一旦在循环体内执行到一个return语句,return语句将会结束该方法,循环自然也随之结束。与continue和break不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。
结束本次循环,然后持续进行下一次循环。
break用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到break,系统将完全结束循环,开始执行循环之后的代码。
null 关键字是表示不引用任何对象的空引用的文字值。 null是引用类型变量的默认值。 普通值类型不能为 null,可为空的值类型除外。
在 C# 中,new 关键字可用作运算符、修饰符或约束。
public class BaseC
{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
new public void Invoke() { }
}
在此示例中,使用 DerivedC.Invoke 隐藏了 BaseC.Invoke。 字段 x 不受影响,因为未使用类似名称将其隐藏。
class ItemFactory<T> where T : new()
{
public T GetNewItem()
{
return new T();
}
}
//当与其他约束一起使用时,new() 约束必须最后指定:
public class ItemFactory2<T>
where T : IComparable, new()
{ }
当与其他约束一起使用时,new() 约束必须最后指定:
public class ItemFactory2<T>
where T : IComparable, new()
{ }
当与其他约束一起使用时,new() 约束必须最后指定:
public class ItemFactory2<T>
where T : IComparable, new()
{ }
Docs .NET C# 指南 语言参考 关键字