语法基础

C#图解教程笔记20170721

2017-07-22  本文已影响32人  李大_C

接口声明可以有任何的访问修饰符public,internal,protected和private。
接口的成员是隐式public的,不允许有任何访问修饰符


image.png

只有类和结构才能实现接口

关于实现接口:

接口是引用类型
接口不仅仅是类和结构要实现的成员列表,它是一个引用类型
从类对象引用获取接口引用的实例

image.png
image.png
这段代码输出结果为:
Calling through: object.
Calling through: interface.

接口和as运算符
当尝试强制转换类对象引用为类未实现的接口的引用,强制转换操作会抛出一个异常。可以通过使用as运算符来避免

image.png

实现多个接口

实现具有重复成员的接口
如果一个类实现了多个接口,那么其中一些接口有相同签名和返回类型的成员。类可以实现单个成员来满足包含重复成员的接口


多个接口的引用

image.png

派生成员作为实现
实现接口的类可以从他的基类继承实现的代码

image.png

显示接口成员实现
使用限定接口名称来声明,有接口名称和成员名称以及他们中间的点分隔符号构成

访问显示接口成员实现
显示接口成员实现只可以通过指向接口的引用来访问,也就是说其他的类成员都不可以直接访问它们。

image.png

接口可以继承接口
接口本身可以从一个或多个接口继承
结果接口包含它声明的所有接口和所有基类的成员。

image.png

转换

用户自定义转换

image.png
image.png

is运算符
is运算符语法如下,expr是源表达式

image.png
如果expr成功转换为目标类型,运算符返回true
is运算符只可用于引用转换以及装箱和拆箱转换,不能用于用户自定义转换

as运算符
as运算符语法如下,expr是源表达式

image.png
targettype是目标类型,他必须是引用类型
转换失败返回null

泛型

c#提供了五种泛型:类,结构,接口,委托和方法。前四个是类型,方法是成员
这是为多段代码在不同的数据类型执行相同指令的情况专门设计的


int型类
float型类
泛型类声明

声明泛型类

image.png

创建构造类型
要替代类型参数的真实类型叫做类型实参

image.png
image.png

创建变量和实例

image.png
image.png
 class MyStack<T>
    {
        int StackPointer = 0;
        T[] StackArray;
        public void Push(T x)
        {
            if (!IsStackFull)
            {
                StackArray[StackPointer++] = x;
            }
        }
        public T Pop()
        {
            return (!IsStackEmpty)
                ? StackArray[--StackPointer]
                : StackArray[0];
        }
        const int MaxStack = 10;
        bool IsStackFull
        {
            get
            {
                return StackPointer >= MaxStack;
            }
        }
        bool IsStackEmpty
        {
            get
            {
                return StackPointer <= 0;
            }
        }
        public MyStack()
        {
            StackArray = new T[MaxStack];
        }
        public void Print()
        {
            for (int i = StackPointer-1; i >=0; i--)
            {
                Console.WriteLine("value:{0}",StackArray[i]);
            }
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            var stackInt = new MyStack<int>();
            var stackString = new MyStack<string>();

            stackInt.Push(3);
            stackInt.Push(5);
            stackInt.Push(7);
            stackInt.Print();
            stackString.Push("Generics are great!");
            stackString.Push("Hi there!");
            stackString.Print();
            Console.ReadKey();
        }
    }

返回结果为:
value:7
value:5
value:3
value:Hi there!
value:Generics are great!


非泛型 泛型
源代码大小 更大:我们需要为每一种类型进行一个新的实现 更小:不管构造类型的数量有多少,我们只需要一个实现
可执行大小 无论每一个版本的栈是否会被使用。都会在编译的版本中出现 可执行文件中只会出现有构造类型的类型
写的难易度 易于书写 比较难写
维护的难易度 更容易出问题,因为所有修改需要应用到每一个可用的类型上 易于维护,因为只需要修改一个地方

非泛型栈和泛型栈

类型参数的约束
要让泛型变得更有用,我们需要提供额外的信息让编译器知道参数可以接受哪些类型。这些额外的信息叫做约束。只有符合约束的实参才能用于类型参数。
Where子句
每一个有约束的类型参数有自己的where子句

image.png
image.png
约束类型

where子句可以以任何次序列出,然而,where子句中的约束必须有特定的顺序:


泛型接口

image.png
输出结果为:
5
Hi There.

使用泛型接口的示例
实现同一泛型接口的两个不同接口

image.png
泛型接口的名字不会和非泛型接口的名字冲突

泛型委托


image.png
image.png

泛型方法

image.png
调用泛型方法
image.png
image.png
泛型方法示例
image.png
image.png

扩展方法和泛型类
和非泛型扩展方法一样,泛型类的扩展方法:

介绍LINQ

class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 15, 5, 25 };
            IEnumerable<int> lowNums =          //定义并储存查询
                from n in numbers
                where n < 10
                select n;
            foreach (var item in lowNums)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }

输出结果如下:
2
5


匿名类型

image.png
匿名类型实例

匿名类型的对象初始化器还有其它两种允许的形式:简单标识符和成员访问表达式。这两种形式叫做投影初始化器。


image.png

查询语法和方法语法

LINQ中from子句和foreach语句主要的不同点

join子句

image.png
image.png image.png
image.png
image.png

let子句
let子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符

image.png
where子句
image.png

orderby

image.png

查询中的匿名类型


image.png

group子句

image.png

异步

namespace yibu
{
    delegate long MyDel(int first, int second);         //声明委托类型
    class Program
    {
        public static long Sum(int x,int y)            //声明异步方法
        {
            Console.WriteLine("                 inside sum");
            Thread.Sleep(3000);                       //挂起三秒
            return x + y;
        }
        static void Main(string[] args)
        {
            MyDel del = new MyDel(Sum);                //创建委托并引用
            Console.WriteLine("异步调用之前");
            IAsyncResult iar = del.BeginInvoke(3, 6, null, null);   //开始异步调用
            Console.WriteLine("异步调用之后");
            Console.WriteLine("Doing stuff");
            long result = del.EndInvoke(iar);           //等待结束并获取结果
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }
}

输出结果为:


异步调用之前
异步调用之后
Doing stuff
inside sum
9


image.png
image.png
image.png
上一篇下一篇

猜你喜欢

热点阅读