MiCoos 哟,写bug呢?

C#基础 类与对象

2019-08-21
GHMicoos

概述:类及类成员。

零 类及类成员简介

0.类

  • 类:创建对象的模板。
  • C#中的一切皆是类与类的实例(对象)。

1.类的访修饰符

  • 一般类:
    • public:公开的,公共的。
    • internal:程序集内部的。
  • 嵌套类:嵌套类是类的成员,所以可以使用类成员的访问修饰符。

2.类的成员

  • 数据成员
    • 字段
    • 常量
    • 事件
  • 函数成员
    • 方法
    • 属性
    • 构造函数
    • 终接器
    • 运算符
    • 索引器
    • 嵌套类型

一 类成员的访问修饰符

0.类成员的访问修饰符:

  • public:公开的,无限制,全部的类都可以访问。
  • protected:派生类中可访问。
  • internal:同一个程序集内的其他的类可访问。
  • private:只能在本类的内部访问。
  • protected internal:在派生类或者同一个程序集内的类可访问。
  • private internal:在派生类且是同一个程序集内的类才可以访问。

  • 在类的内部类的成员都是可以访问的

二 字段

  • 默认是实例的,使用static修饰符变成静态的。
  • 一般把字段设置为private,然后调用方法来更改字段。(数据封装)

三 常量

0.readonly与cont区别

  • const
    • 只能在声明时候赋值。
    • 只能赋值编译时候能确定的值,一般是字面量。
    • 在程序编译过程中,会把常量转换为字面量,如此一来如果更改了字面量然后在编译,那么之前编译的版本值不会变。
    • 常量默认是static的,但是不能显式加上static。
  • readonly
    • 可以在声明时候赋值,也可以在构造函数中赋值。
    • 可以赋值变量。
    • 可以是实例的,也可以是静态的。

四 方法

  • 默认是实例的,使用static修饰符变成静态的。
  • C#中除非特别指定,否则所有的参数都是传值
  • ref参数(引用参数):要求对传递给方法的参数进行初始化。
  • out参数(输出参数):传递变量给方法时候可以不进行初始化,但是在方法中必须对变量进行赋值。
  • 参数数组:有时候希望参数的数量是可变的。
    • 参数数组必须是方法声明中的最后一个参数
    • 调用者可以为参数数组指定零个参数,这会造成包含零个数据项的一个数组。
  • 命名参数:传递参数给方法时参数需要按照一定的顺序;但是命名参数运行按任意顺序传递。
  • 可选参数:可选参数必须是方法定义的最后一个参数,必须给可选参数定义默认值。
/// <summary>
/// 引用参数
/// </summary>
/// <param name="refParam"></param>
 public static void  RefParamMethod(ref int refParam)
     //refParam参数,传入必须初始化
     =>refParam = 2;

/// <summary>
/// 输出参数
/// </summary>
/// <param name="outParam"></param>
 public static void OutParamMethod(out int outParam)
     //outParam参数,在传入前可以不用初始化,但是必须在方法中赋值
     =>outParam = 2;

/// <summary>
/// 用于测试方法 命名参数调用
/// </summary>
/// <param name="oneParam"></param>
/// <param name="twoParam"></param>
 public static void NameParamMethod(int oneParam, int twoParam)
     => Console.WriteLine("NameParamMethod函数。");

/// <summary>
/// 参数数组
/// 1.参数数组不一定是方法声明中的唯一采参数。但是,参数数组必须是方法声明中的**最后一个参数**。
/// 由于只有最后一个参数才能是参数数组,所以方法最多只能有一个参数数组。
/// 2.调用者可以为参数数组指定零个参数,这会造成包含零个数据项的一个数组。
/// 3.参数数组是类型安全的--传入参数类型必须匹配与数组指定的类型。
/// 4.调用者可以显示地使用一个数组,而不是以逗号分割的参数列表。最终生成的CLI代码是一样的。
/// 5.假如目标方法的实现要求一个最起码的参数数量,请在方法声明中显示指定必须提供的参数。
/// </summary>
/// <param name="outParam"></param>
 public static void ParamArrayMethod(params int[] paramArray)
 {
     Console.Write("传入的参数:");
     foreach (var param in paramArray)
     {
         Console.Write($" {param} ");
     }
     Console.WriteLine();
 }

/// <summary>
/// 可选参数
/// </summary>
/// <param name="oneParam"></param>
/// <param name="optionalParam"></param>
 public static void OptionalParamMethod(int oneParam, int optionalParam = default(int))
     => Console.WriteLine($"传入的参数:{oneParam} {optionalParam}");


 static void Main(string[] args)
 {
     /*引用参数 ref*/
     int a = 1;
     //输出:ref,调用方法前,a=1。
     Console.WriteLine($"ref,调用方法前,a={a}。");
     RefParamMethod(ref a);
     //输出:ref,调用方法后,a=2。
     Console.WriteLine($"ref,调用方法后,a={a}。");
     Console.WriteLine($"------------------------------");

     /*输出参数 out*/
     int b;
     OutParamMethod(out b);
     //输出:out,调用方法后,a=2。
     Console.WriteLine($"out,调用方法后,a={b}。");
     Console.WriteLine($"------------------------------");

     /*参数数组*/
     //传入0个参数,方法中是空数组
     //输出:传入的参数:
     ParamArrayMethod();
     //单个单个传入数组
     //输出:传入的参数: 1  2  3
     ParamArrayMethod(1,2,3);
     //传入数组
     //输出:传入的参数: 4  5  6
     ParamArrayMethod(new int[] { 4, 5, 6 });
     Console.WriteLine($"------------------------------");

     /*命名参数*/
     //不使用命名参数
     NameParamMethod(1,2);
     //使用命名参数
     NameParamMethod(twoParam:2,oneParam:1);
     Console.WriteLine($"------------------------------");

     /*可选参数*/
     //不传入 可选参数
     //输出:传入的参数:1 0
     OptionalParamMethod(1);
     //传入 可选参数
     //输出:传入的参数:1 2
     OptionalParamMethod(1, 2);
     Console.WriteLine($"------------------------------");

     Console.WriteLine("键入任何键,退出。。。");
     Console.ReadKey();
 }

四 方法的重载

  • 方法签名:方法名相同,但是参数个数/参数类型不同。(方法返回类型不是方法签名的关注点)
  • 重载:方法的几个版本有不同的签名。
  • 重载方法:不能仅在方法的返回类型上有区别,也不能仅仅根据参数是声明为out还是ref来区分。

public static void OverloadMethod()
    => Console.WriteLine($"void OverloadMethod()");
public static void OverloadMethod(int one)
    => Console.WriteLine($"void OverloadMethod(int one)");
///// <summary>
///// 返回类型不是签名的一部分
///// </summary>
///// <returns></returns>
//public static bool OverloadMethod()
//    => default(bool);
///// <summary>
///// 不能仅仅是参数的传递类型区别
///// </summary>
///// <param name="one"></param>
//public static void OverloadMethod(out int one)
//    => Console.WriteLine($"void OverloadMethod(int one)");

五 属性

0.定义

  • 它是一个方法或一对方法,在客户端代码看来,它是一个字段。

1.只读/只写属性

  • 定义:缺省对应的访问器。
  • 这是不好的编程方式,因为这样可能会使客户端代码的作者干到迷惑。一般情况下,如果要用,最好使用一个方法代替。
    private string _Name;
    public string Name
    {
      get{return _name}
    }
    

    2.属性访问器的访问修饰符

    • 没有显式指定访问器的访问修饰符,那么默认为属性的访问修饰符级别。
    • 在get/set访问器中,必须有一个具备属性的访问级别。 ``` js

private string _Name; public string Name { //protected get{return _Name;}会编译错误, 必须有一个访问器具备属性的访问级别 get{return _Name;} private set{_Name=value} }


#### **3.自动实现属性**
  * 如果属性的set/get访问器没有任何逻辑,就可以使用自动实现属性。
  * 自动实现属性编译器会自动生成私有字段(语法糖)。
  * 每个访问器的访问级别可以不同。但是不能缺省访问器。

``` js

public string Name{get;private set;}

5.属性作为虚字段使用

  • 属性的行为与虚字段相似,某些情况下,甚至根本不需要一个支持字段。相反,可以让属性的取值方法放回一个计算好的值,而让赋值方法解析值,并把它持久存储到其他一些成员字段中。所以,属性不允许作为ref或者out参数值使用。

public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
    get { return FirstName + LastName; }
    private set { }
}

六 构造函数

0.构造函数

  • 函数名与类名相同,但是没有返回值(返回值不能是void)。

1.默认构造函数

  • 它能把所有的成员字段初始化为类型的默认值。
  • 如果类不提供构造函数,编译器会自动生成一个默认的构造函数。
  • 如果类提供了构造函数,编译器就不会自动提供默认构造函数。

2.静态构造函数

  • 编写静态构造函数的原因:类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些字段和属性。
  • 静态构造函数只执行一次,即在代码引用类之前调用它,通常在第一次调用类的任何成员之前执行静态构造函数。
  • .NET运行库没有确保什么时候执行静态构造函数,也不能预计不同类的静态构造函数的执行顺序。
  • 静态构造函数没有访问修饰符,其他C#代码从来不调用它。
  • 一个类只能有一个静态构造函数。

3.调用本类的其他构造函数

  • 使用this关键字

public class MyClass
{
    public static readonly int MaxValue;

    /// <summary>
    /// 静态构造函数
    /// </summary>
    static MyClass()
    {
        MaxValue = 100;
    }

    public int Age { get; set; }
    private int height { get; set; }

    public MyClass():this(0,0)
    {

    }

    public MyClass(int age,int height)
    {
        Age = age;
        this.height = height;
    }
}


Similar Posts

上一篇 C#基础 运算符

下一篇 C#基础 弱引用

Comments