C# 教程 在线

2411C# 命名空间(Namespace)

using的用法:

1. using指令:引入命名空间

这是最常见的用法,例如:

using System;
using Namespace1.SubNameSpace;

2. using static 指令:指定无需指定类型名称即可访问其静态成员的类型

using static System.Math;var = PI; // 直接使用System.Math.PI

3. 起别名

using Project = PC.MyCompany.Project;

4. using语句:将实例与代码绑定

using (Font font3 = new Font("Arial", 10.0f),
            font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

代码段结束时,自动调用font3和font4的Dispose方法,释放实例。

2410C# 运算符重载

operator 关键字用于在类或结构声明中声明运算符。运算符声明可以采用下列四种形式之一:

public static result-type operator unary-operator ( op-type operand )
public static result-type operator binary-operator ( op-type operand, op-type2 operand2 )
public static implicit operator conv-type-out ( conv-type-in operand )
public static explicit operator conv-type-out ( conv-type-in operand )

参数:

  • result-type 运算符的结果类型。
  • unary-operator 下列运算符之一:+ - ! ~ ++ — true false
  • op-type 第一个(或唯一一个)参数的类型。
  • operand 第一个(或唯一一个)参数的名称。
  • binary-operator 其中一个:+ - * / % & | ^ << >> == != > < >= <=
  • op-type2 第二个参数的类型。
  • operand2 第二个参数的名称。
  • conv-type-out 类型转换运算符的目标类型。
  • conv-type-in 类型转换运算符的输入类型。

注意:

前两种形式声明了用户定义的重载内置运算符的运算符。并非所有内置运算符都可以被重载(请参见可重载的运算符)。op-type 和 op-type2 中至少有一个必须是封闭类型(即运算符所属的类型,或理解为自定义的类型)。例如,这将防止重定义整数加法运算符。

后两种形式声明了转换运算符。conv-type-in 和 conv-type-out 中正好有一个必须是封闭类型(即,转换运算符只能从它的封闭类型转换为其他某个类型,或从其他某个类型转换为它的封闭类型)。

运算符只能采用值参数,不能采用 ref 或 out 参数。

C# 要求成对重载比较运算符。如果重载了==,则也必须重载!=,否则产生编译错误。同时,比较运算符必须返回bool类型的值,这是与其他算术运算符的根本区别。

C# 不允许重载=运算符,但如果重载例如+运算符,编译器会自动使用+运算符的重载来执行+=运算符的操作。

运算符重载的其实就是函数重载。首先通过指定的运算表达式调用对应的运算符函数,然后再将运算对象转化为运算符函数的实参,接着根据实参的类型来确定需要调用的函数的重载,这个过程是由编译器完成。

任何运算符声明的前面都可以有一个可选的属性(C# 编程指南)列表。

using System;
using System.Collections.Generic;
using System.Text;

namespace OperatorOverLoading
{
    class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student(20, "Tom");
            Student s2 = new Student(18, "Jack");
            Student s3 = s1 + s2;

            s3.sayPlus();
            (s1 - s2).sayMinus();
            Console.ReadKey();
        }
    }
    public class Student
    {
        public Student() { }
        public Student(int age, string name)
        {
            this.name = name;
            this.age = age;

        }
        private string name;
        private int age;

        public void sayPlus()
        {
            System.Console.WriteLine("{0} 年龄之和为:{1}", this.name, this.age);

        }
        public void sayMinus() {
            System.Console.WriteLine("{0} 年龄之差为:{1}", this.name, this.age);
        }
        //覆盖“+”操作符
        public static Student operator +(Student s1, Student s2)
        {
            return new Student(s1.age + s2.age, s1.name + " And " + s2.name);

        }
        //覆盖“-”操作符
        public static Student operator -(Student s1, Student s2) {
            return new Student(Math.Abs(s1.age - s2.age), s1.name + "And" + s2.name);
        }
   }
}

2409C# 多态性

自己写了个继承,分别写了隐藏方法跟重写方法,生成三个实例来演示一下。

namespace MySpace
{
    class dad
    {
        protected string name;
        public dad(string n)
        {
            name = n;
        }
        public void say()
        {
            Console.WriteLine("I am {0}.", name);
        }
        public virtual void growup()
        {
            Console.WriteLine("{0} has grown old.", name);
        }
    }
    class son:dad
    {
        public son(string n) : base(n)
        {
            //name = n;
        }
        public new void say()
        {
            Console.WriteLine("I am {0} and a son.",name);
        }
        public override void growup()
        {
            //base.growup();
            Console.WriteLine("{0} is growing up.",name);
        }
    }
    class entrance
    {
        public static void Main()
        {
            dad grandpa = new dad("grandpa");
            grandpa.say();
            grandpa.growup();
            dad father = new son("father");
            father.say();
            father.growup();
            son tom = new son("Tom");
            tom.say();
            tom.growup();
            Console.ReadKey();
        }
    }
}

运行结果为:

I am grandpa.
grandpa has grown old.
I am father.
father is growing up.
I am Tom and a son.
Tom is growing up.

上边的结果:

  • 1)用父类生成的父类对象,grandpa,访问隐藏方法是父类的方法,访问重写方法是父类的方法
  • 2)用子类生成的父类对象,father,访问隐藏方法是父类的方法,访问重写方法是子类的方法
  • 3)用子类生成的子类对象,son,访问隐藏方法是子类的方法,访问重写方法是子类的方法

2408C# 多态性

原文中抽象类的例子其实没有体现多态性,可以再加一个继承类(三角形面积),以体现多态。

using System;
namespace PolymorphismApplication
{
    abstract class Shape
    {
        public abstract int area();
    }
    
    class Rectangle : Shape
    {
        private int length;
        private int width;
        public Rectangle(int a = 0, int b = 0)
        {
            length = a;
            width = b;
        }
        public override int area()
        {
            //Console.WriteLine("Rectangle 类的面积:");
            return (width * length);
        }
    }

    class triangle : Shape
    {
        private int baseLine;
        private int height;
        public triangle(int a = 0, int b = 0)
        {
            baseLine = a;
            height = b;
        }
        public override int area()
        {
            //Console.WriteLine("三角形类的面积:");
            return (2 *baseLine* height/4);
        }
    }

    class RectangleTester
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle(10, 7);
            double a = r.area();
            triangle t = new triangle(10, 7);
            double b = t.area();
            Console.WriteLine("长方形面积: {0}, 三角形面积:{1}", a, b);
            Console.ReadKey();
        }
    }
}

2407C# 多态性

虚方法的调用:调用上,使用子类构造的对象调用虚方法,就会调用子类的方法,使用父类构造的对象,就会调用父类的方法。

隐藏方法的调用:调用上, 使用子类类型的声明调用隐藏方法,就会调用到子类的方法。若想调用被隐藏的方法,需要用父类类型的声明来调用。

调用不同的举例:

class Enemy
{
    public void Move() {
        Console.WriteLine("调用了 enemy的move方法");
    }
    public virtual void Attack() {
        Console.WriteLine("enemy attac");
    }
    }


    class Boss : Enemy
    {
    public override void Attack() {
        Console.WriteLine("Boss Attac");
    }

    public new void Move() {
        Console.WriteLine("Boss move");
    }
}

static void Main(string[] args)
{
    //---- 隐藏方法的调用----begin
    Boss oneEnemy = new Boss();
    oneEnemy.Move(); // 调用的是隐藏方法, 用子类的声明来调用的,调用的就是子类的Move。

    Enemy twoEnemy = new Boss();
    twoEnemy.Move(); // 调用的隐藏方法, 用父类的声明来调用的,调用的就是父类的Move方法。
    //-----------------------end

    //-----虚方法的调用----- begin
    用什么类型 来构造,在调用方法的时候就会调用什么类型的方法。

    Enemy threeEnemy = new Enemy();
    threeEnemy.Attac(); // 调用虚方法,用父类来实例化的,所以调用的是父类的Attac方法。

    Enemy fourEnemy = new Boss();
    fourEnemy.Attac();  // 调用虚方法,用子类来实例化的,所以调用的就是子类(Boss)的Attac方法。

    //-----虚方法的调用------end

    Console.ReadKey();
}