1.public
: 公有的,是类和类成员的访问修饰符,访问不受限制
2.private
: 私有的,是一个成员访问修饰符,不能修饰类,只有在声明它的类和结构内部可以访问
3.internal
: 内部的,是类和类成员的访问修饰符,同一个程序集中的所有类都可以访问,可访问性低于public
4.protected
: 受保护的,是一个成员访问修饰符,只能在它的类和派生类中访问
5.protected internal
: 访问限于当前程序集或派生类
6.private protected
: 访问限于当前程序集中该类的派生类或该类内部
private
、protected
、protected internal
或private protected
不能修饰类
简而言之,一个程序集就是一个项目,一个命名空间,一个dll文件
注意点:
如果在成员声明中未指定访问修饰符,则使用默认的访问修饰符
类/枚举/接口/结构体默认访问修饰符是internal,仅限该程序集内部访问
默认的成员可访问性 | 该成员允许声明的可访问性 | |
class | private | public protected internal private protected internal |
struct | private | public internal private |
interface | public | 无 |
enum | public | 无 |
Example:
namespace TestModifier
{
public class Class1
{
//访问不受限制
public string namePublic = null;
//当前程序集
internal string nameInternal = null;
//只能在类内部访问
private string namePrivate = null;
//只能在该类及其派生类内部使用
protected string nameProtected = null;
//当前程序集及派生类
protected internal string nameProtectedInternal = null;
//C# 7.2 该类及其派生类内部使用
private protected string namePrivateProtected = null;
}
class Class2 : Class1
{
private string name1;
private string name2;
private string name3;
private string name4;
private string name5;
public void Method1()
{
name1 = new Class1().namePublic;
name2 = new Class1().nameInternal;
name3 = new Class1().nameProtectedInternal;
//派生类
name4 = base.nameProtected;
//派生类
name5 = base.namePrivateProtected;
}
}
}
1.partical
: 在整个同一程序集中定义分部类和分部方法。在处理大型项目或自动生成的代码(如 Windows 窗体设计器提供的代码)时,在多个文件间拆分类、结构或接口类型可能会非常有用。分部类型可以包含分部方法。
分部类:
处理大型项目时,使一个类分布于多个独立文件中可以让多位程序员同时对该类进行处理
当使用自动生成的源文件时,你可以添加代码而不需要重新创建源文件。 Visual Studio 在创建Windows 窗
体、Web 服务包装器代码等时会使用这种方法。 你可以创建使用这些类的代码,这样就不需要修改由
Visual Studio生成的文件
若要拆分类定义,请使用 partial 关键字修饰符
class Program
{
///
/// 声明修饰符
/// partical: 分部类和分部方法
///
///
static void Main(string[] args)
{
A a = new A();
a.GetParticalMethod("xiaomi");
}
///
/// 分部方法:
/// 分部类型各部分中的签名必须匹配
/// 方法必须返回void
/// 不允许使用访问修饰符.分部方法是隐式专用的,仅限内部使用
///
partial class A
{
//定义分部方法
partial void MethodA(string s);
///
/// 运行分部方法
///
public void GetParticalMethod(string s)
{
MethodA(s);
}
}
partial class A
{
partial void MethodA(string s)
{
Console.WriteLine("Something happened: {0}", s);
}
}
}
2.static
: 声明属于类型本身而不是属于特定对象的成员
3.abstract
: 指示被修改的实现已丢失或不完整。abstract修饰符可用于类
、方法
、属性
、索引
、事件
。
namespace AbstractModifier
{
class Program
{
static void Main(string[] args)
{
AbstractClassTest test = new B();
//调用继承基类的方法
test.M();
//调用虚拟方法重载的抽象方法
test.N();
//调用接口抽象方法实现
test.Test();
Console.Read();
}
}
public class A
{
public void M()
{
Console.WriteLine("测试");
}
public virtual void N()
{
Console.WriteLine("方法名为N");
}
}
public interface I
{
void Test();
}
///
/// 抽象类继承类A,实现接口I
///
public abstract class AbstractClassTest : A, I
{
///
/// 重载的普通方法
///
//public override void N()
//{
// base.N();
//}
///
/// 接口方法的实现的普通方法
///
//public void Test()
//{
// throw new NotImplementedException();
//}
///
/// 重载的抽象方法
///
public abstract override void N();
///
/// 接口方法的实现的抽象方法
///
public abstract void Test();
}
public class B : AbstractClassTest
{
public override void N()
{
Console.WriteLine("抽象重载方法的实现");
}
public override void Test()
{
Console.WriteLine("接口方法的实现的抽象方法的实现");
}
}
}
namespace AbstractModifier
{
///
/// 抽象类
///
class Program
{
static void Main(string[] args)
{
var o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine($"x = {o.X}, y = {o.Y}");
Console.Read();
}
}
public abstract class BaseClass
{
protected int _x = 10;
protected int _y = 10;
public abstract void AbstractMethod();
public abstract int X { get; }
public abstract int Y { get; }
}
public class DerivedClass : BaseClass
{
public override int X => _x + 10;
public override int Y => _y + 10;
public override void AbstractMethod()
{
base._x++;
base._y++;
}
}
}
输出结果:
x = 21, y = 21
4、sealed:
密封类禁止继承,普通类中的方法或属性也可用 sealed 修饰,但普通类中的方法或属性必须与 override 关键字结合使用,那么该普通类中的方法或属性在其基类中必须与virtual关键字结合使用
可以对替代基类中的虚方法或属性的方法或属性使用 sealed 修饰符。 这使你可以允许类派生自你的类并防止它们替代特定虚方法或属性。
public class A
{
protected virtual int m { get; set; }
protected virtual void Test1()
{
Console.WriteLine("这是虚方法1");
}
protected virtual void Test2()
{
Console.WriteLine("这是虚方法2");
}
}
public class B : A
{
protected override sealed int m { get => base.m; set => base.m = value; }
protected override sealed void Test1()
{
base.Test1();
}
protected override void Test2()
{
base.Test2();
}
}
public sealed class C : B
{
///
/// 这里只能重载Test2,其父类的Test1方法重载为密封方法了
///
protected override void Test2()
{
base.Test2();
}
}
5.virtual: 修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写
6.override: 扩展或修改继承的抽象或虚拟实现的方法、属性、索引器或事件需要 override 修饰符
class Program
{
static void Main(string[] args)
{
Shape square = new Square(2);
Console.WriteLine($"Area of Square is {square.GetArea()}");
Console.Read();
}
}
public abstract class Shape
{
public abstract int GetArea();
}
///
/// 正方形
///
public class Square : Shape
{
private int side;
///
/// 设置正方形边长
///
/// 正方形边长
public Square(int n) => side = n;
///
/// 返回正方形边长
///
///
public override int GetArea() => side * side;
}
7.new: 做修饰符该关键字可以显式隐藏从基类继承的成员。隐藏继承的成员时,该成员的派生版本将替换基类版本,作运算符,用于创建对象和调用构造函数
虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。如果使用 new 来显式隐藏成员,将禁止此警告
如果用父类新建子类,如: Base dclass= new Derived();dclass.Method()是调用了基类的method()方法,而不是子类的
override 可以覆盖基类的方法,让基类的方法以子类的内容实现;而 new 不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已
public class BaseC
{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
public new void Invoke() { }
}
8.extern: 声明在外部实现的方法。extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。在这种情况下,还必须将方法声明为 static