C#学习速记_定义类成员

成员定义

修饰符含义
public可以由任意代码访问
无 或 private只能由类中的的代码访问,默认关键字
internal只能由定义它的程序集(项目)内部的代码访问
protected由类或派生类中的代码访问
protected internal只能由程序集中派生类的代码访问
  • static,类成员,而非实例成员;可有于定义字段、属性、方法
  • const,用于定义常量,通过类直接访问
  • readonly,用于定义变量,只能由构造函数赋值或定义变量时初始化赋值

定义字段

  • 公共字段以 PascalCasing 形式定义,私有字段推荐以 pascalCasing 形式定义

class MyClass
{
    public int MyInt;
    int myString;
    
    public readonly double MyDouble = 20.32D;
    public static float MyFloat = 3.14F;
    
    const float PI = 3.1415926F;  
    
}

定义方法

  • 公共方法以 PascalCasing 形式定义
  • 以 static 定义的方法,只能过类访问
修饰符含义
virtual方法可以重写
abstract方法必须在非抽象派生类中重写(只能用于抽象类中)
override方法重写一个基类方法(重写方法时,必须用此关键字)
extern方法定义放在其它地方

public class MyBaseClass
{
    // virtual 基类定义可重写
    public virtual void DoSomething()
    {
        // Base implementation.
    }
}

public class MyDerivedClass : MyBaseClass
{
    // override 派生类实现了重写
    public override void DoSomething()
    {
        // Derived class implementation, override base implementation.
    }
}

public class MyDerivedClass1 : MyBaseClass
{
    // override 派生类实现了重写,sealed 但指出其子类不能再重写
    public sealed override void DoSomething()
    {
        // Derived class implementation, override base implementation.
    }
}

定义属性

  • 公共属性以 PascalCasing 形式定义

  • 至少包含 get 或者 set

  • get 必须有返回值,类型为属性类型,一般与私有这段关联

  • 不能同时为 get 与 set 指定访问控制

  • get 与 set 的访问控制要比属性本身严格

  • set 中通过 value 关键字来给字段赋值

  • 可以 set 中编写值校验来决定是否执行赋值

  • 4种处理 set 校验失败后,不赋值的策略(推荐 3 与 4

    1. 什么也不做
    2. 给字段赋默认值
    3. 继续执行,但记录下该事件
    4. 抛出异常

private int myInt;

public int MyInt { get => myInt; set => myInt = value; }


// 只有 get 没有 set
private int myDoubledInt = 2;
public int MyDoubledIntProp => (myDoubledInt * 2);

重构成员

编写字段后,通过代码编辑器由系统自动生成属性


private string stringHello;
public string StringHello { get => stringHello; set => stringHello = value; }

自动属性

不定义字段,由编译器自动生成。

  • 只能通过属性访问,因为字段由系统生成,不知道名字
public string StringHello = {
    get;
    set;
}

public string StringHello = { get; set; }

// 只有 get 的自动属性
public string StringHello = { get; }

// 自动属性初始化

public string StringHello = { get; } = "Hello";


类成员的其他主题

隐藏基类方法

  • 隐藏用 new , 重写用 override
  • 无论基类是否使用 virtual 定义,都可以用 new 来隐藏
  • 派生类虽然隐藏了基类的方法,但仍可以通过基类来调用

public class MyBaseClass
{
    public void DoSomething()
    {
        // Base implementation.
    }
}

// 系统会发警告,提示隐藏一个基类成员
public class MyDerivedClass : MyBaseClass
{
    public void DoSomething()
    {
        
        // Derived Class implementation,hides base implementation.
    }
}

// 采用 new 强制隐藏
public class MyDerivedClass : MyBaseClass
{
    new public void DoSomething()
    {
        
        // Derived Class implementation,hides base implementation.
    }
}


调用重写或隐藏的基类方法

  • 派生类中通过 base 来调用隐藏了的基类方法

public class MyBaseClass
{
    public virtual void DoSomething()
    {
        // Base implementation.
    }
}


public class MyDerivedClass : MyBaseClass
{
    public override void DoSomething()
    {
        base.DoSomethind();
        // Derived Class implementation,hides base implementation.
    }
}

this

  • 表示对当前对象的引用
  • 不能在 static 成员中使用 this
  • 最常用的功能:将当前对象实例的引用传递给一个方法;限制局部类型的成员。
// 将当前对象实例的引用传递给一个方法
public void doSomething()
{
    MyTargetClass myObj = new MyTargetClass();
    myObj.DoSomethingWith(this);
}

// 限定局部类型的成员
public class MyClass
{
    private int someData;
    public int SomeData
    {
        get
        {
            return this.comeData;
        }
    }
}

嵌套的类型定义

// 定义
public class ClassC
{
    public class ClasssD
    {
        public override string ToString()
        {
           return "D";
        }
    }
}

// 使用

ClassC.ClasssD myC = new ClassC.ClasssD();
Console.WriteLine(myC.ToString());

  • 私有嵌套类,可以阻止空间内其他成员对其的访问
  • 嵌套类可以访问其包含类的私有和受保护成员
// 定义
public class ClassA
{
    private int state = -1;
    public int State
    {
        get { return state; }
    }
    public class ClassB
    {
        public void SetPrivateState(ClassA target, int newState)
        {
            target.state = newState;
        }
    }
}

// 使用
ClassA myObject = new ClassA();
Console.WriteLine($"myObject.State = {myObject.State}");

ClassA.ClassB myOtherObject = new ClassA.ClassB();
myOtherObject.SetPrivateState(myObject, 999);
Console.WriteLine($"myObject.State = {myObject.State}");

// 结果

myObject.State = -1
myObject.State = 999

接口的实现

  • 所有接口成员都是隐式公共(public)的,不能使用访问修饰符(public/private/protected/internal都不行)
  • 接口成员不能包含实现代码
  • 接口成员不能定义字段成员
  • 不能使用 static/virtual/abstract/sealed 来定义接口成员
  • 禁止类型定义成员
  • 可以使用 new 来隐藏基类成员
  • 至少定义属性的 get 与 set 存取器中的一个
  • 接口可以被定义为类成员,但不能定义为其他接口的成员

// 隐藏
interface IMyBaseInterface
{
    void DoSomething();
}

interface IMyDerivedInterfalce : IMyBaseInterface
{
    new void DoSomething();
}

// 属性

interface IMyInterface
{
    int MyInt { get; set; }
}

在类中实现接口

  • 实现接口的类必须包含该接口所有成员的实现代码,必须是公共的,属性必须匹配指定的 get 与 set
  • 可以使用 virtual 与 abstract 来实现接口成员,但不能使用 static 或 const
// 实现接口定义
interface IMyInterface
{
    void DoSomething();
    void DoSomethingElse();
}

public class MyClass : IMyInterface
{
    void DoSomething() {
        // 实现
    }
    void DoSomethingElse() {
         // 实现
    }
}


// 隐式实现
interface IMyInterface
{
    void DoSomething();
    void DoSomethingElse();
}

class MyBaseClass
{
    public void DoSomething() {} // 注意必须是 public
}

class MyDerivedClass : MyBaseClass, IMyInterface
{
    // 隐式已实现 DoSomething()
    
    public void DoSomethingElse() {}
}


// 重写
public interface IMyInterface
{
    void DoSomething();
    void DoSomethingElse();
}

class MyBaseClass : IMyInteface
{
    public virtual void DoSomething() {}
    public virtual void DoSomethingElse() {}
}

// 版本1
class MyDerivedClass : MyBaseClass
{

    public override void DoSomething() {}
    public override void DoSomethingElse() {}
}


// 版本1调用
IMyInteface myInteface = myClass;

myInteface.DoSomething();
myInteface.DoSomethingElse();

// 版本1结果

// MyDerivedClass 的 DoSomething 与 DoSomethingElse 方法

// 版本2
class MyDerivedClass : MyBaseClass
{
    public new void DoSomething() {}
    public new void DoSomethingElse() {}
}


// 版本2调用
IMyInteface myInteface = myClass;

myInteface.DoSomething();
myInteface.DoSomethingElse();

// 版本2结果

// MyBaseClass 的 DoSomething 与 DoSomethingElse 方法


显示实现接口成员

只能通过接口来访问,不能通过类来访问


public interface IMyInterface
{
    void DoSomething();
    void DoSomethingElse();
}

public class MyClass : IMyInterface
{
    void IMyInterface.DoSomething() {} // 显示实现接口成员
    public void DoSomethingElse() {} // 隐式实现接口成员
}

MyClass myClass = new MyClass();
myClass.DoSomething() // 报错
myClass.DoSomethingElse();

IMyIntefalce myIntefalce = myClass;

myIntefalce.DoSomething(); // 只能通过此种方式来访问
myIntefalce.DoSomethingElse();

其它属性存取器

对于隐式实现接口时,在接口中定义属性时只实现了 get 或 set 时,可以在类中添加另外的 get 或 set


public interface IMyInterface
{
    int MyIntProperty { get; }
}

// 版本1
public class MyClass1 : IMyInterface
{
    public int MyIntProperty { get ; set; // 添在没有在接口中实现的 set }
}

MyClass1 myClass = new MyClass1();
myClass.MyIntProperty = 100;

IMyInterface myInterface = myClass;
int myInt = myInterface.MyIntProperty ;
myInterface.MyIntProperty = 200; // 报错,因为是在派生类中实现的

版本2 
public class MyClass1 : IMyInterface
{
    public int MyIntProperty { get ; protected set; // 只能在类及派生类中访问 }
}

MyClass1 myClass = new MyClass1();
myClass.MyIntProperty = 100; // 报错

部分类定义

  • 通过 #region 来在代码编辑器折叠代码,使代码更容易阅读
  • 使用 partial 关键字,将类的定义分散在多个文件中
  • partial 必须出现在每个文件中类定义的相同部分
  • 多个部分类也只能有一个基类
  • 多个部分类实现的不同接口,最后编译时会合并在一起
// region
public Myclass
{
    #region Fields
    private int myInt;
    #endregion
    
    ...
    
    #region Methods
    public void DoSomething()
    {
        // Do something ...   
    }
    #endregion
}

// partial

public partial class MyClass : MyBaseClass, MyInterface1 {}
public partial class MyClass : MyBaseClass, MyInterface2 {}

// 等价于

public class MyClass : MyBaseClass, MyInterface1, MyInterface2 {}

部分方法定义

  • 部分方法使用 partial 关键字定义
  • 在一个部分类中定义部分方法,但没有方法体,在另一个部分类中实现方法体
  • 部分方法可以是静态的,但总是私有的,且不能有返回值
  • 部分方法的参数,不能是 out ,可以是 ref
  • 部分方法不能使用 virtual, abstract, override, new, sealed, extern 修辞符
  • 部分类的作用体现在编译代码时,而不是使用代码时
  • 代码编译时,如果代码中发现一个未实现的部分方法,会直接删除此方法及相关的引用,优化性能
// 部分方法

public partial class MyClass
{
    partial void MyPartialMethod(); // 此处定义
}

public partial class MyClass
{
    partial void MyPartialMethod()
    {
        // Method implementation,此处实现
    }
}

// 调用未实现的部分类

public partial class MyClass
{
    partial void DoSomethingElse();
    
    public void DoSomething() {
        Console.WriteLine("DoSomething 开始");
        DoSomethingElse(); // 调用部分方法
        Console.WriteLine("DoSomething 结束")
    }
}

public partial class MyClass
{
    // 此没有实现 DoSomethingElse 方法
}

// 输出结果

DoSomething 开始
DoSomething 结束

转载于:https://my.oschina.net/moyung2014/blog/1813478

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值