• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
冥海
博客园    首页    新随笔    联系   管理    订阅  订阅

C#知识点整理综合

———————————————————数据类型————————————————

◆◆1.仓库与盒子的使用——数据类型与变量

(1)变量被用来存储特定类型的数据。

把应用程序的内存看做是一个仓库,把变量看做是存放数据的盒子。

 

(2)盒子的选择也就是变量的选择。

 

(3)变量的声明是指定变量的名称和类型。

①未经声明的变量本身并不合法

②变量必须初始化,即变量必须被赋值才能使用。

 

(4)变量的作用域就是可以访问该变量的代码区域。

 

(5)允许空值的变量 null

null不是0或空字符串,代表的意义是"未定义","未设定"

当允许一开始不设定初始值,也不用赋值的情况时,可以在数据类型后面加?号。

int?age=null;

 

 

◆◆2.数据类型之值类型的使用

(1)基于值类型的都分配在堆栈上,一旦离开其定义的作用域,立即就会从内存中删除。

 

(2)值类型数据:

①简单类型:所有的简单类型都是.Net Framework系统类型的别名,例如:int 是System.Int32的别名。

 

②结构类型:把一组相关的信息放在一起,把一系列相关的变量组成一个单一实体过程。

这个单一实体的类型就是结构类型。每一个变量称为结构的成员。

★★结构类型采用struct进行声明。

 

★★结构类型也是一种封装,即把相关事物的属性和方法封装在一起

简单的结构封装,同类一样可以带构造函数。

struct Employee

{

public string empname;

public int Age;

}

 

③枚举类型

 

 

(3)所有的值类型都隐式的继承自System.ValueType类,该类又继承自object类

所有值类型都是隐式密封的,在堆栈中进行分配,提高性能。

 

◆◆3.数据类型之引用类型的使用

所有被称为“类”的都是引用类型,包括类,接口,数组和委托等。

 

指向数据的指针或引用,引用类型为null时表示没有引用任何对象。

 

这些对象一直保存在内存中,直到.Net垃圾回收器将他们销毁。

 

对一个引用类型的赋值,将产生对该堆上同一个对象的新引用。

 

变量按引用进行传递

 

(1)结构类型,值类型

class Program

{

   static void Main(string[] args)

    {

            int v1 = 0;

            int v2 = v1;

            v2 = 987;

            Console.WriteLine("{0},{1}", v1, v2);

 

 

            C c1 = new C();

            C c2 = c1;

            c2.value = 987;

            Console.WriteLine("{0},{1}", c1.value, c2.value); 0,987

 

            Console.ReadKey();

 

     }

}

 

 

struct C  //结构类型,值类型

{

            public int value;

 

}

 

 

(2)声明了一个类,引用类型

class Program

{

   static void Main(string[] args)

    {

            int v1 = 0;

            int v2 = v1;

            v2 = 987;

            Console.WriteLine("{0},{1}", v1, v2);

 

 

            C c1 = new C(); 对类的引用

            C c2 = c1;

            c2.value = 987;

            Console.WriteLine("{0},{1}", c1.value, c2.value); 987,987

 

            Console.ReadKey();

 

     }

}

 

 

class C  //声明了一个类,引用类型

{

            public int value;

 

}

 

 

 

★★★★尽管值类型和引用类型存在着差异,但是二者都有实现接口的能力,支持任意数量的字段,属性,事件和常量。

 

 

 

 

———————————————————if for switch的使用————————————

◆◆4.岔路口的选择——if语句的使用

只有()里的内容为被满足为真的情况下才会执行{}里的代码。

 

如果光一个if(){},那么存在着缺陷,即如果不满足条件,就不会做任何处理,也不返回任何结果。

而使用了

if()

{}

else()

{}

则可避免这个缺陷。

★★★★if语句的嵌套使用。

 

◆◆5.春夏秋冬——switch的使用

(1)switch 语句后面可以跟 sbyte,byte,short,ushort,int,uint,long,ulong,char,string和枚举类型。

(2)每个case后面跟着的【常量表达式】必须与【表达式】的类型相同,且是一个常量,不能是变量.

(3)两个或多个case指定同一个常数值,就会导致编译出错。

 

 

 

◆◆6.for语句,如果不设置循环条件,程序就会产生死循环。

for(初始值;不尔表达式;更新值)

{

语句块

}

 

下面来看一个无限循环的例子

int i = 0;

for (; ; )

{

   i++;

   Console.WriteLine(i);

}

 

 

 

———————————————————数组的使用———————————————

◆◆7.数组

(1)包含相同类型变量的集合,所有成员必须具有相同的类型

(2)这些变量可以通过索引进行访问,数组的索引从0开始

(3)数组中的变量称为数组的元素。元素都具有唯一的索引与之相对

(4)数组能够容纳元素的数量称为数组的长度。

(5)数组的维数即数组的

(6)数组类型是从System.Array派生的引用类型,可分为一维,多维和交错数组。

 

 

★★二维数组的使用★★★

(1)二维数组的声明

★★.Net索引值一律是从0开始的。

int[,]=new int[4,5]

第一维的长度是4,索引的下标是0 1 2 3

第二维的长度是5,索引的下标是0 1 2 3 4

 

(2)

int[,] inti = new int[4, 5] { { 1, 2, 3, 4 ,5}, { 1, 2, 3, 4,5 }, { 1, 2, 3, 4,5 }, { 1, 2, 3, 4,5 }};

 

for (int i = 0; i < 4; i++)

{

    for (int j = 0; j < 5; j++)

   {

     Console.WriteLine(inti[i, j]);

               

   }

           

}

 

 

(3)清除个别数组元素以外的其他成员Array.Clear(清除的数组元素,起始索引,要清除的个数)

string[] s = { "张三", "王俊", "刘一江" };

Array.Clear(s, 1, 2);

 

foreach (string s1 in s)

Console.WriteLine(s1);   //清除数组s中,索引为1的元素,清除2个,最后输出 ""

Console.ReadKey();

 

 

 

———————————————————字符串的比较——————————————

◆◆8.字符串的比较

(1)判读两个字符串是否一致,即一摸一样

string s1 = "abcd";

string s2 = "ABcd";

int i = s1.CompareTo(s2);

if (i == 0)

{

   Console.WriteLine("相等");

}

else

{

   Console.WriteLine("不相等");

}

 

 

(2)用Equals进行比较

string s = "abcdefg";

Console.WriteLine(s.Length);

//②比较两个字符串的范围,忽略大小写,字符顺序是否一样

//s.Equals(new string,StringComparison.OrdinalIgnoreCase)

if (s.Equals("abcdEFG", StringComparison.OrdinalIgnoreCase))

Console.WriteLine("这是两个一样的字符串");

else

Console.WriteLine("两个字符串不一致");

 

//③比较两个字符串大小写是否一样 s.Equals(newstring)

if (s.Equals("abcdefg"))  //两个字符串如果相同则返回True值

{

  Console.WriteLine("两个字符串一样");

}

else

{

  Console.WriteLine("两个字符串不一样");

}

 

 

(3)字符串对比一般都用: if(str1==str2){ } , 但还有别的方法:

①string str1; str2

//语法: str1.EndsWith(str2); __检测字串str1 是否以字串str2 结尾,返回布尔值.如:

if(str1.EndsWith(str2)){ Response.Write("字串str1 是以"+str2+"结束的"); }

②

//语法:str1.Equals(str2); __检测字串str1 是否与字串str2 相等,返回布尔值,用法同

上.

③

//语法Equals(str1,str2); __检测字串str1 是否与字串str2 相等,返回布尔值,用法同

上.

 

 

(4)比较两个数的大小

比较两个数的大小 System.Math.Max(i, j)

int i = 10;

int j = 5;

int x = System.Math.Max(i, j);

MessageBox.Show(x.ToString());

 

 

———————————————————字符串函数———————————————

◆◆9.字符串函数的专讲

(1)常用的一些字符串函数

 

//①给出一个字符串,首先要测试出这个字符串的长度

//用length 还可以"" 字符串的长度,null则无法测试出长度

//因为null不指定存储空间,所以无法测试长度

//length 1个汉字占一个字节

string s = "abcdefg";

Console.WriteLine(s.Length);

 

//②比较两个字符串的范围,忽略大小写,字符顺序是否一样

//s.Equals(new string,StringComparison.OrdinalIgnoreCase)

if (s.Equals("abcdEFG", StringComparison.OrdinalIgnoreCase))

Console.WriteLine("这是两个一样的字符串");

else

Console.WriteLine("两个字符串不一致");

 

//③比较两个字符串大小写是否一样 s.Equals(newstring)

if (s.Equals("abcdefg"))  //两个字符串如果相同则返回True值

{

  Console.WriteLine("两个字符串一样");

}

else

{

  Console.WriteLine("两个字符串不一样");

}

 

//④字符串劈开split函数

//1)简单的字符串劈开函数  s1.Split('|')

★分开的是数组,而不是字符串

string s1 = "aa|bb|c";

string[] f = s1.Split('|');   //是'' 而不是" "    

foreach (string e in f)

Console.Write(e);

Console.WriteLine();

 

//2)劈开一个字符,组成字符串数组

//RemoveEmptyEntries移除空的字符串数组元素  none 保留空的字符串数组元素。

string[] f1 = s1.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

foreach (string e1 in f1)

Console.WriteLine(e1);

 

//3)string[] f3 = s.Split('我') 只能劈开单个字符

string[] f2 = s1.Split(new string[] { "我是" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string e2 in f2)

Console.WriteLine(e2);

//⑤敏感字符的判断

//1)字符串中是否有子串 是否有敏感字符串  s.Contains("社会") || s.Contains("和谐")

string str1 = "我们的社会真和谐啊!!!";

if (str1.Contains("社会") || str1.Contains("和谐"))

Console.WriteLine("禁止出现敏感词汇");

//2)敏感词汇进行*掩藏

string str = "社会真和谐啊,构造和谐社会!!!";

            if (str.Contains("和谐"))

            {

                char[] temp = str.ToCharArray();

                for (int i = 0; i < temp.Length; i++)

                {

                    if (temp[i] == '和' && temp[i + 1] == '谐')

                    {

                        temp[i] = '*';

                        temp[i + 1] = '*';

                    }

                }

                string s3 = new string(temp);

                Console.WriteLine(s3);

                Console.ReadKey();

            }

//⑥字符串大小写转换 ToLower()  ToUpper()string strbs = "abcde";

Console.WriteLine(strbs.ToLower());//全部转换成小写的形式

Console.WriteLine(strbs.ToUpper());//全部转换成大写的形式

 

//⑦修剪字符串中出现的空格

string strspace = "  aaa    bbb    ccc    ";

Console.WriteLine("原始字符串是:{0}|", strspace);

Console.WriteLine("没有修剪之前的字符串长度,{0}", strspace.Length);

Console.WriteLine("\n");

 

Console.WriteLine("修剪两边字符串后是:{0}|", strspace.Trim());

Console.WriteLine("修剪两边字符串后的长度,{0}", strspace.Trim().Length);

Console.WriteLine("\n");

 

Console.WriteLine("修剪字符串开始位置后是,{0}|", strspace.TrimStart());

Console.WriteLine("修剪字符串开始位置后长度,{0}", strspace.TrimStart().Length);

Console.WriteLine("\n");

 

Console.WriteLine("修剪字符串结束位置后是,{0}|", strspace.TrimEnd());

Console.WriteLine("修剪字符串结束位置后长度,{0}", strspace.TrimEnd().Length);

//⑧字符串替换函数 s.Replace(oldstring,newstring ); 字符串替换  

Console.WriteLine("\n");

string strreplace = "高山|长江|黄河|北京";

strreplace = strreplace.Replace("|", ",");

Console.WriteLine(strreplace); //高山,长江,黄河,北京

//⑨

//s.Substring(startIndex, length)  开始的索引  截取长度

string strsub = "高山|长江|黄河|北京";

strsub = strsub.Substring(3, 3);

Console.WriteLine(strsub);

 

//三元运算符   i==5?"是":"否"

int inti = 5;

string strsub2 = (inti == 5 ? "是" : "否");

Console.WriteLine(strsub2);

 

string strsub3 = "高山|长江";

strsub3 = strsub3.Substring(2, strsub3.Length - 2 > 5 ? 5 : strsub3.Length - 2);

// 或者 s = s.Substring(2,Math.Min(s.Length-2,5));

Console.WriteLine(strsub3);

Console.ReadKey();

 

 

Equals判断对象是否想等。

如果不在指向同一存储地址的话,那么肯定不想等,如果指向同一内存地址的话,再进行判断。

字符串进行判断的是两个对象的值,而不是对象。

// test t = new test();

            t.Name = "a";

            test t1 = new test();

            t1.Name = "a";

            t.Equals(t1);

   class test

    {

        public string Name;

        public override bool Equals(object obj)

        {

            return this.Name == ((test)obj).Name;

        }

}

 

 

 

 

 

 

 

 

 

(2)ToString()的使用

12345.ToString("n"); //生成 12,345.00

12345.ToString("C"); //生成 ¥12,345.00

12345.ToString("e"); //生成 1.234500e+004

12345.ToString("f4"); //生成 12345.0000

12345.ToString("x"); //生成 3039 (16进制)

12345.ToString("p"); //生成 1,234,500.00%

 

(3)如何在指定范围内产生随机函数 ran.Next(10, 20)

Random ran = new Random();

textBox1.Text = Convert.ToString(ran.Next(10, 20));

 

(4)日期函数

DateTime 数字型

System.DateTime currentTime=new System.DateTime();

1.1 取当前年月日时分秒

currentTime=System.DateTime.Now;

1.2 取当前年

int 年=currentTime.Year;

1.3 取当前月

int 月=currentTime.Month;

1.4 取当前日

int 日=currentTime.Day;

1.5 取当前时

int 时=currentTime.Hour;

1.6 取当前分

int 分=currentTime.Minute;

1.7 取当前秒

int 秒=currentTime.Second;

1.8 取当前毫秒

int 毫秒=currentTime.Millisecond;

 

(5)在指定的字符串中 插入函数Insert()

在字串中指定索引位插入指定字符。如:

str1.Insert(1,"字");在str1 的第二个字符处插入“字”,如果str1="中国",插入后

为“中字国”;

 

(6)在字串左(或右)加空格或指定char 字符,使字串达到指定长度

PadLeft()、PadRight()

<%

string str1="中国人";

str1=str1.PadLeft(10,'1'); //无第二参数为加空格

Response.Write(str1); //结果为“1111111 中国人” , 字串长为10

%>

———————————————————可空类型与全角字符转换为半角——————

◆◆10.一无所有——可空类型

C#通过在数据类型关键字后面紧跟着符号?可以定义可空类型,即允许该变量类型有空值

int?x=null;

char?[] ch=new char?[]{'a',null,'b'};

 

(2)C#还提供了一个二元运算符为可空类型赋值

int? x=null;

int? y=x??5;  //如??左边的值为null,那么返回??右边的值,否则返回左边的值

 

(3)int? 等价于 System.Nullable<int>

 

◆◆11.半壁江山——全角字符转换为半角

(1)全角字符:一个字符占两个标准字符位置,汉字字符,规定了全角的英文字符,特殊字符,图形符号都是全角字符。

1 2 3 a b c ?

(2)半角字符

一字符占用一个标准的字符位置,通常的英文字母,数字,符号都是半角的。以ASCII方式的字符。

123abc?

 

——————————————————C#高级语法————————————————

◆◆12.编写高质量的C#程序

(1)如何进行换行

①某两个表达式项之间将其断开

if (f == ImageFormat.Jpeg.Guid ||

    f == ImageFormat.Tiff.Guid ||

 

double containerAspectRatio =

    (double)container.ClientWidth / container.ClientHeight;

 

Rectangle imageBounds = new Rectangle(

    itemBounds.X + padding,

 

②编译器总是按行来进行设计的,将多条语句写在一行会引起不必要的麻烦

 

③使用空行分隔代码块

 

④使用空格降低代码密度

 

⑤在每一行的代码左端空出一部分长度,更加清晰地从外观上体现出程序的层次结构

 

⑥在“选项”对话框中对C# 编辑器的代码缩进方式进行设置(如图1-2),选择“插入空格”模式。

◆◆13.c#中布尔类型的值true和false都是小写的包括头字母

 

◆◆14.C#中using创建一个别名

using Con = System.Console;

Con.WriteLine("123");  //使用你创建的别名

Con.ReadKey();

 

◆◆15.C#不允许使用关键字作为标识符。虽然使用关键字作为标识符名称是不可取的但有时使用

其他语言的代码可能会需要使用关键字作为标识符。在这种情况下可以在关键字前面加一个

@符号用在标识符。

int @int = 10;

MessageBox.Show(@int.ToString());

 

◆◆16.获取本机的IP地址

System.Net.IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;

String strIp = addressList[0].ToString();

MessageBox.Show(strIp);

 

◆◆17.//获取应用程序运行路径

string myAppPath = Application.ExecutablePath;  //获取当前程序的路径

int nIndex = myAppPath.LastIndexOf(@"\");       //找到最后一个\的索引

myAppPath = myAppPath.Substring(0, nIndex);     //从第0个到最后一个的索引就是本程序的路径

MessageBox.Show(myAppPath);

 

◆◆18.OpenFileDialog的使用

//设置初始目录

openFileDialog.InitialDirectory = strPath;

//设定可选择的文件类型

openFileDialog.Filter = "图标|*.ico|Bitmap图像|*.bmp|JPEG图像|*.jpg";

//默认的文件类型

openFileDialog.FilterIndex = 1;

openFileDialog.RestoreDirectory = false;

//第一个或者最后一个文件的名称

openFileDialog.FileName = "";

if (this.openFileDialog.ShowDialog() == DialogResult.OK)

◆◆19.进度条的显示

progressBar1.Value = 30;//表示进度为30%

 

◆◆20.使系统发出蜂鸣声、报警声等

SystemSounds.Beep.Play();//(Beep / Exclamation / Question / Head);

 

◆◆21.程序集

Assembly 一堆类打一个包

.Net中有程序集的概念,托管代码   在.Net framework中运行,可以进行反编译

★★★程序中只引用必须的程序集,减小程序的尺寸

一些程序集得内部类不允许外部进行访问. internal

★★★只能单向进行引用,不能进行圈式引用 即 A引用B B引用A

 

◆◆22.全局程序集 GAC

 

◆◆23.垃圾回收

垃圾回收解放了手工管理对象的工作,提高了程序的健壮性,但副作用就是程序代码可能对于对象创建变得随意。

 

(1)避免不必要的对象创建★★★★★避免创建不必要的对象

由于垃圾回收的代价较高,所以C#程序开发要遵循的一个基本原则就是避免不必要的对象创建。以下列举一些常见的情形。

 

(2)避免循环创建对象 ★★★★★创建对象的时候不要在循环中进行创建

如果对象并不会随每次循环而改变状态,那么在循环中反复创建对象将带来性能损耗。高效的做法是将对象提到循环外面创建。

 

(3)在需要逻辑分支中创建对象 ★★★★★懂得对象在作用域中创建,一离开作用域就释放

如果对象只在某些逻辑分支中才被用到,那么应只在该逻辑分支中创建对象。

 

(4)使用常量避免创建对象

程序中不应出现如 new Decimal(0) 之类的代码,这会导致小对象频繁创建及回收,正确的做法是使用Decimal.Zero常量。我们有设计自己的类时,也可以学习这个设计手法,应用到类似的场景中。

 

 

 

 

——————————————String的操作———————————————————

◆◆24.String 操作

(1)String是不变类,使用 + 操作连接字符串将会导致创建一个新的字符串。如果字符串连接次数不是固定的,例如在一个循环中,则应该使用 StringBuilder 类来做字符串连接工作。因为 StringBuilder 内部有一个 StringBuffer ,连接操作不会每次分配新的字符串空间。只有当连接后的字符串超出 Buffer 大小时,才会申请新的 Buffer 空间

StringBuilder sb = new StringBuilder(256 );

for ( int i = 0 ; i < Results.Count; i ++ )

{

sb.Append (Results[i]);

}

 

如果连接次数是固定的并且只有几次,此时应该直接用 + 号连接,保持程序简洁易读。实际上,编译器已经做了优化,会依据加号次数调用不同参数个数的 String.Concat 方法。例如:String str = str1+ str2 + str3 + str4;

 

(2)避免不必要的调用 ToUpper或 ToLower 方法

String是不变类,调用ToUpper或ToLower方法都会导致创建一个新的字符串。如果被频繁调用,将导致频繁创建字符串对象。这违背了前面讲到的“避免频繁创建对象”这一基本原则。

例如,bool.Parse方法本身已经是忽略大小写的,调用时不要调用ToLower方法。

 

另一个非常普遍的场景是字符串比较。高效的做法是使用 Compare 方法,这个方法可以做大小写忽略的比较,并且不会创建新字符串。

 

还有一种情况是使用 HashTable 的时候,有时候无法保证传递 key 的大小写是否符合预期,往往会把 key 强制转换到大写或小写方法。实际上 HashTable 有不同的构造形式,完全支持采用忽略大小写的 key: new HashTable(StringComparer.OrdinalIgnoreCase)。

 

(3)最快的空串比较方法

将String对象的Length属性与0比较是最快的方法:if (str.Length == 0)其次是与String.Empty常量或空串比较:if (str == String.Empty)或if (str == "")

注:C#在编译时会将程序集中声明的所有字符串常量放到保留池中(intern pool),相同常量不会重复分配。

 

(4)拼装字符串

if (str.Length == 0 )

str = vals[i].ToString();

else

str += " , " + vals[i].ToString(); 

 

其实这种写法非常自然,而且效率很高,完全不需要用个Remove方法绕来绕去。

 

(5)避免两次类型转换

 

 

 

 

 

 

 

 

 

 

 

 

———————————C#中readonly与const的区别———————————————◆◆25.C#中readonly与const的区别

(1)他们都是常量类型 readonly 运行时常量  const编译时常量

 

(2)readonly也称为只读变量

 

(3)工作原理(readonly保持引用方式,而const则替换成常量)

public static readonly int A = 2; //A为运行时常量

public const int B = 3; //B为编译时常量    下面的表达式:

 

int C = A + B;   

int C = A + 3; 

经过编译后与下面的形式等价:

可以看到,其中的const常量B被替换成字面量3,而readonly常量A则保持引用方式。

 

 

(4)声明及初始化

readonly 只能声明为类字段,支持实例类型或静态类型

可以在声明的同时初始化,或在函数中进行初始化

 

const出了可以声明为类字段之外,还可以声明为方法中的局部常量。

默认为static,无需进行修饰,但必须在声明的时候进行初始化.

 

 

(5).数据类型支持

由于const在编译时替换成字面量,所以取值受一定的限制,日期类型无法进行声明

而readonly则可以进行声明

public const DateTime D = DateTime.MinValue;    改成readonly就可以正常编译:

 

(6)可维护性

readonly 以引用方式进行工作,某个常量更新后,所有引用该常量的地方都能得到更新后的值

const则无法做到这点

 

在下面两种情况下:

a.取值永久不变(比如圆周率、一天包含的小时数、地球的半径等)

b.对程序性能要求非常苛刻

可以使用const常量,除此之外的其他情况都应该优先采用readonly常量。

 

 

 

 

 

 

————————————————C#面向对象——————————————————

◆◆26.枚举

//限定变量的取值范围,确定个数 bool 类型可以用枚举,只是.Net内置了bool类型,所以没人这么做

//QQ的在线,隐身。。

static void Main(string[] args)

{

  Gender g = Gender.Fremal;

  Console.WriteLine(g);

  Gender g1 = Gender.Man;

  Console.WriteLine(g1);

Console.ReadKey();

 

}

 

enum Gender { Man,Fremal,Unkown}

 

 

◆◆27.函数

//对一堆代码进行重用的一种机制,可能有输入的值(参数),可能有返回的值

返回值: Console.ReadLine(); 读取后有一个返回的值

参数:   Console.WriteLine(Console.ReadLine());

// int i = Convert.ToInt32("123");

(1)有声明返回值的

static void Main(string[] args)

{

   int inti = Readint(); //接收函数返回的值

   Console.WriteLine(inti);

   Console.ReadKey();

}

 

 

static int Readint()

{

   return 30;            //return后跟上函数返回的值

}

 

(2)没有声明返回值的 void

static void Main(string[] args)

{

  int inti = Readint();

  SayHellow();

  Console.WriteLine(inti);

  Console.ReadKey();

}

static void SayHellow()

{

   Console.WriteLine("abc");

   return;

   return 100;     //报错,由于是void所以报错。

}

 

(3)如果我想要通过void返回值,怎么办?

1)参数是字符类型string

static void Main(string[] args)

{

   string s = "Hellow";

   Str(s);                 //按值传递,外部不影响内部的值

   Console.WriteLine(s);

   Console.ReadKey();

}

 

static void Str(string strs)

{

  strs = "abc";

}

 

 

2)如果想影响的话,如何进行?

//参数的前面加上ref 按照引用传递,内部的值影响外部的值。

//①传递字符类型  

static void Main(string[] args)

{

     string s = "Hellow";

     string s1 = Str(ref s);

     Console.WriteLine(s1);

     Console.ReadKey();

}

 

static string Str( ref string strs)

{

     strs = "abc";

     return strs;

}

 

 

 

 

//②传递int类型

static void Main(string[] args)

{

  int a = 100;

  SayHellow(a);  // void—int 不能用隐式转换,必须显示转换.

  Console.WriteLine(a);

  Console.ReadKey();

}

 

      

static void SayHellow(int j)

{

    j = 10;

  

}

 

(4) 下列关于构造函数的描述正确的是(c)理解构造函数和函数重载的区别

a)构造函数可以声明返回类型。//构造函数连返回值都没有,如何声明返回类型?

b)构造函数不可以用private修饰

c)构造函数必须与类名相同    //这个是对的。

d)构造函数不能带参数 //没有参数和不能带参数是两回事

 

class A

{

   public A()

    {

    Console.WriteLine("钩爪子");

    }

 

   

}

 

 

★★★首先理解如何构造函数(构造函数和函数重载不是一回事,构造函数是名称和类名一样的特殊函数

而函数重载是几个相同函数名使用了一些规则后,可以同时存在)

 

构造函数是用来创建对象的特殊函数,函数名和类名一样,没有返回值,连void都不用

构造函数可以有参数,默认情况下是没有参数的构造函数,记住没有没有参数和不能有参数是两回事

 

 

 

 

(5)函数的重载,就是函数的重名,

//只有参数的类型、顺序不一致才能函数重名,函数返回值类型一致与否没关系

//构成重载的条件:参数类型不同或者参数个数不同(不严谨的),与返回值无关。

(1)static void Main(string[] args)

{

  SayHellow(123);

  Console.ReadKey();

}

 

 

static void SayHellow(string  a)

{

  Console.WriteLine("您好啊!!!");

}

 

 

static void SayHellow(int n)

{

Console.WriteLine(102);

}

 

 

(6)理解什么是可变参数 以不确定个数的数组方式进行传递的就是可变参数。

★★★可变参数就是参数的

可变参数params 可变参数必须放到最后,即最后一个参数是可变参数

个数不确定的可变参数以数组的形式传递

static void Main(string[] args)

        {

 

 

            Inta(10, "11", "22", "33", "44"); 

 

 

            Console.ReadKey();

 

        }

static void Inta(int i, params string[] s)    //可变参数必须放到最后一位,因为确定的参数传递完后,剩下的都是可变参数,否则则无法进行确定。

        {

            foreach (string a in s)

                Console.WriteLine(a);

            Console.WriteLine(i);

 

        }

(7)如何理解对象的引用

int datetime,bool,char等类型都属于值类型(ValueType),赋值的时候是传递拷贝

普通的对象则是引用类型,赋值的时候是传递引用。我指向谁,兄弟你也来指向。

★★一个对象会占很大的内存,是大家共用一份。

 

 

 

◆◆28.如何理解 类的概念?抽象、摸不到的 而对应的具体的是对象。

面向对象 = 对象 + 类 + 继承 + 通信 。如果一个软件系统是使用这样四个概念来设计的,我们认为这个软件系统是面向对象的。

 

 

 

◆◆29.对使用可访问性级别的限制 ★★★基类的可访问性必须大于子类的可访问性

(1)基类的可访问性必须不小于派生类。

(2)~~~~派生类的可访问性必须不大于基类。

(3)~~~~成员的可访问性至少是包含它的类。

例子:

Class BaseClass{};

Public class MyClass: BaseClass{};

这是错误的!!!!!!!!!!!!!!!!

 

类是个抽象的,对一些具有相同特征事物的一个抽象,比如一个班有同学,是一个抽象,具体到某

一个人是对象,笔记本电脑就是一个类,具体某一个人的笔记本电脑是对象。

类不占内存,对象才占内存。

static void Main(string[] args)

{

   Person per = new Person();

   per.name = "张三";

   per.age = 25;

   per.height = 180;

   Console.WriteLine("姓名为:{0},年龄为:{1},身高为{2}CM", per.name, per.age, per.height);

   Console.ReadKey();

 

}

   

class Person

{

    public string name { get; set; }

    public int age { get; set; }

    public int height { get; set; }

}

◆◆30.如何不使用Public 声明字段,被调用?

为什么要用属性来声明,是为了在类中控制非法或合法值

而用public字段则无法进行合法值的判断

属性不会存储值,而是由相应的字段保存值

属性后不要加()

 

//用简写方式不能只有get或者只有set。不合理

//public int Height

//{

//   get

//}

 

 

★★

a.SetAge(20);

Console.WriteLine(a.GetAge());

public int GetAge()

{

   return age;

}

public void SetAge(int _age)

{

  this.age = _age;

}

 

 

★★也可以这样调用类得方法

int t = a.SetAge(40);

Console.WriteLine(t);

public int SetAge(int _age)

{

   if (_age > 30)

   this.age = _age;

   else

   {

     this.age = 100;

   }

     return this.age;

}

 

(1)可以用字段来接收属性设置的值,并进行返回

private string name1;

public string Name1

{

     get

     {

       return this.name1;

     }

           

    set

     {

       value = "理解万岁";

       this.name1 = value; //字段的值接收方法的值,可以对方法进行设置

     }

 

}

 

(2)先通过方法进行更改,然后再通过属性进行返回值的操作。

p.giveName("张三"); //先把值传递给方法,然后再进行接收

Console.WriteLine(p.Name); p.属性名

private string name;

        public string Name     //属性再去接收方法赋予字段里的值

        {

 

            get

            {

                return this.name;

            }

        }

 

public void vname(string sname)  //先接收传过来的值,然后进行修改 字段里接收方法赋予的值

        {

            if (sname == "张三")

            {

                sname = "李四";

                this.name = sname;

            }

        }

 

 

 

 

 

 

 

 

 

◆◆32.如何理解继承?

(1)简单的 子类继承父类,其实也就是子类指向子类继承父类的字段,属性,方法。

class Progra

{

    static void Main(string[] args)

     {

        B b = new B();

        b.Say();

        Console.ReadKey();

    }

}

 

class A

{

        public string name { get; set; }

 

        public int age { get; set; }

 

public void Say()

        {

            Console.WriteLine("您好啊");

 }

}

class B : A{    }

(2)如果想让父类指向子类,该如何做?

class Progra

{

    static void Main(string[] args)

     {

        A a = new A();

        B b =(B)a; //这样就会报错,如果不想报错的话,可以用as    B b =a as B;

       // B b1 = a as B;

        Console.ReadKey();

    }

}

 

 

(3)现在我想让父类调用子类里的方法,如何进行操作?要进行方法重写

★★使用虚方法,就是使用 virtual 关键字来进行修饰,从而达到“多态”的目的

方便以后对代码进行进一步完善。

★★子类可以不进行重写。

class Program

{

   static void Main(string[] args)

    {

            //父类要先指向子类,才能用抽象的方法进行调用

            A a = new B();

            a.Say();

 

            Console.ReadKey();

      }

}

 

 

class A

{

      public string name { get; set; }

      public int age { get; set; }

 

 

      public virtual void Say()

      {

         Console.WriteLine("001");

      }

}

 

 

(4)除了使用上面的方法,还有没有使子类进行方法重写的呢?

答案是有的,可以使用抽象的方法,进行子类的重写,abstract

★★★就是为了子类去继承,不能new,不能实例化的

static void Main(string[] args)

{

     //父类要先指向子类,才能用抽象的方法进行调用

        A a = new B();

        a.Say();

 

        Console.ReadKey();

}

   

 

abstract class A

{

       public string name { get; set; }

       public int age { get; set; }

       abstract public void Say();  //★★★这里声明抽象的,那么类也要是抽象的。

 

}

 

class B : A

{

        public override void Say()

        {

            Console.WriteLine("子类说Say");

            this.name = "张三丰";

            Console.WriteLine("我叫张三丰");

        }

}

 

 

 

 

 

(5)★★父类用  abstract 子类必须进行重写  子类也不能用new。

★★父类用virtual 子类可以用new不进行重写,那么就只能自己使用,不允许调用和继承。

 

 

(6)如果父类声明一个属性或字段,只想在本类中进行使用,不允许别人进行访问的话,可以用private

★★声明private的话,子类也不允许访问,继承。

那么如果只想子类进行继承,不允许别人访问的话,用用protected,相当于遗产保护。

protected void Name()

{

  Console.WriteLine("输出姓名");

}

 

 

 

◆◆33.如何理解成员访问级别

(1)理解什么是成员?

★★字段、方法、属性  都可以叫做类的成员  都需要定义访问级别

访问级别的用处在于控制成员在哪些地方可以被访问,这样达到面向对象中“封装”的目的。

public(任何地方都可以访问);

private(默认级别。只能由本类中的成员访问)

 

(1)

p.Height = 180;

 

class Person

{

        private string name { get; set; }

        public int age { get; set; }

       

 

        private int height;//外部程序无法调用private 声明的height

        public int Height

        {

            get

            {

                return this.height;    //内部使用的话,需要

            }

            set

            {

 

                this.height = Height;

            }

 

        }

}

 

 

◆◆34.如何理解全局变量(static)与变量,常量之间的区别。

变量与常量的区别

(1)常量

1)对于任何的对象的值都不变,所以不需要通过对象来调用,直接通过类名来引用。   类名.常量名

常量一般全部大写,不能进行赋值。

private const double P1 = 3.14;

static void Main(string[] args)

{

   // P1 = 5; 常量不能进行赋值        

   Console .WriteLine(P1);

   M1();

   Console .ReadKey();

}

 

 

 

 

static void M1()

{

   Console.WriteLine(P1*2);    

}

 

 

 

2)PI.P1 类名.常量名

class Program

{

static void Main(string[] args)

    {

       // P1 = 5; 常量不能进行赋值

       Console.WriteLine(PI.P1);

       M1();

       Console.ReadKey();

}

static void M1()

     {

    Console.WriteLine(PI.P1 * 2);

}

}

 

class PI

{

 public const double P1 = 3.14;

}

 

(3)变量 程序易读,一个地方变了,所有地方都变了。

1)以字母或者下划线_开头,后面可以是任意字母,数字或下划线_,但不能是关键字(如class,new,int 在VS中蓝色的为关键字)。

int a3=9;

int _a3=9;

 

2)变量在声明后才能使用

int i3=10;

Console.WriteLine(i3);

变量在使用之前必须赋值

int i1;

i1 = 10;

Console.WriteLine(i1);

 

 

3)变量可以任意进行赋值,如需通过对象来调用的话,那么需要调用类里的属性或方法才能进行使用。

static void Main(string[] args)

{

    Person p1 = new Person();

    p1.age = 25;

    p1.height = 175;

    p1.Name = "张三丰";

   

    Console.WriteLine("姓名为:{0},年龄为:{1},身高为:{2}",p1.Name,p1.age,p1.height);

    Console.ReadKey();

 

}

  

 

class Person

{

  public int age;     //声明名称为age的变量

  public int height;

 

  public string Name  //声明一个名称为Name的属性

   {

     get;

     set;

   }

}

 

//或者这样声明也是可以的。

class Person

{

        public int age;

        public int height;

 

        private string name;

        public string Name  //声明一个名称为Name的属性

        {

          get{ return this.name; }

set{ this.name = value; }

        }

}

 

(4)全局变量static 调用非static成员必须通过对象

class Program

{

  static void Main(string[] args)

  {

    St a = new St();

    a.Hellow();

    St.Say();//静态static 的只能 类名.方法名

    Console.ReadKey();

}

}

 

class St

{

    public void Hellow()

      {    }

static public void Say()

      {    }

}

★★没有对象,即方法名前声明了 static ,那么只能类名.方法名,

★★如果有对象,即方法名前没有声明 static,那么要用一个变量指向类,然后用变量名.方法名

class Program

{

   static void Main(string[] args)

   {

     St.age = 15;

     Console.WriteLine(St.age);

     Console.ReadKey();

    }

}

 

static class St

{

     public static int age;

}

 

 

 

 

下面是两段综合的面向对象的代码

(1)class Program

    {

        static void Main(string[] args)

        { //父类实例化,调用父类的方法

            A a = new A();

            a.Say();

 

            //子类实例化,调用子类的方法

            B b = new B();

            b.Say(); //假设子类的方法,new 了,不允许父类进行调用的话,那么父类调用自己的方法

 

            //父类指向子类,父类调用子类的方法父类用virtual,子类用override进行方法的重写

            a = b;

            a.Say();

            a.Hellow();

 

 

            //子类继承父类的属性,字段,方法

            b.name = "张中秋";

            Console.WriteLine("{0}", b.name);

 

            //子类B的子类C继承A,B可以继承的方法,字段,属性

            //C c = new C();

            //c.Age = 18;

            //Console.WriteLine("子类C可以继承父类A的{0}", c.Age);

 

 

 

            //c.Tel(); //不允许访问父类中私有的private 字段

            //如果想调用父类的限制成员访问级别的

            //那么要在子类的方法中调用父类的,且父类的必须以protected进行声明 ,转到①

            b.Hellow();

 

 

            //继承抽象的父类

            D d = new D();

            d.name = "高明光";

            Console.WriteLine(d.name);

            d.CSay();

 

            //无法调用抽象的子类

            //C c = new C(); //无法创建抽象的类

            //a = c;

          

 

            Console.ReadKey();

 

        }

 

 

 

    }

 

 

    class A

    {

        public string name { get; set; }

 

        private int age;

        public int Age

        {

            get { return this.age; }

 

            set { this.age = value; }

 

        }

 

 

        public int height

        {

            get;

            set;

 

        }

 

 

        public virtual void Say()

        {

 

            Console.WriteLine("父类说您好啊 !!!");

        }

 

 

        public virtual void Hellow()

        {

            Console.WriteLine("父类说Hellow");

        }

 

 

        private string Tel

        {

            get;

            set;

 

 

        }

 

 

        protected string School

        {

            get;

            set;

        }

 

 

        public virtual  void CSay()

        {

            Console.WriteLine("父类可以调用抽象的子类");

        }

 

    }

 

 

    class B : A

    {

        public new void Hellow()

        {

            Console.WriteLine("子类说Hellow2");

            //①

            this.School = "传智播客";

            Console.WriteLine("父类不能直接调用protected,所以我只能在方法中调用{0}", this.School);

        }

 

        public override void Say()

        {

            Console.WriteLine("子类说您好Hellow");

        }

}

abstract class C : B

    {

        public override  void CSay()

        {

            Console.WriteLine("C是抽象的类,不允许被直接调用,只能被继承");

        } 

 }

 

    class D : C

{ 

 

}

 


(2.1)
父类和子类都实例化,指向自己,那么都先调用自己的方法

如果子类没有该方法的话,那么子类才继承父类的方法,否则子类调用自己的方法。

class Program

{

    static void Main(string[] args)

      {

            A a = new A();

            a.Say();  //父类调用父类的方法

 

            B b = new B();

            b.Say(); //子类调用子类的方法,如果子类没有这个方法,才继承父类的方法

 

            Console.ReadKey();

      }

}

 

class A

{

         public void Say()

         {

             Console.WriteLine("父类说");

         }

}

 

 

class B : A 

{

        //public void Say()  //子类如果有方法的话,调用子类自己的方法。

        //{

        //    Console.WriteLine("子类说");

        //}

}

 

(2.2)如果父类指向子类,想调用子类的方法。

(1)那么父类的方法必须声明virtual,子类的方法必须声明为override。

(2)父类是先找到自己本身的方法,如果是virtual进行声明的,

 

那么看看子类是不是override,进行声明的,如果子类是override进行声明的,那么父类可以调用子类的方法。

class Program

{

        static void Main(string[] args)

        {

            A a = new B();

            a.Play();  //调用的是子类的方法

 

            Console.ReadKey();

        }

}

 

class A

{

        public virtual void Play()

        {

            Console.WriteLine("父类说飞起来了");

        }

}

 

 

class B : A

{

        public override void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

 

 

如果父类是virtual进行声明的,而子类不是override进行声明的,那么父类还是调用自己的方法。

class Program

    {

        static void Main(string[] args)

        {

            A a = new B();

            a.Play(); //调用的还是父类的方法

 

            Console.ReadKey();

        }

    }

 

class A

{

        public virtual void Play()

        {

            Console.WriteLine("父类说飞起来了");

        }

}

 

 

class B : A

{

        public void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

如果父类和子类前面没有任何修饰符的话,那么父类虽然指向子类,仍是调用父类的方法。

class Program

{

        static void Main(string[] args)

        {

            A a = new B();

            a.Play(); //调用的是父类的方法

 

            Console.ReadKey();

        }

}

 

class A

{

        public void Play()

        {

            Console.WriteLine("父类说飞起来了");

        }

}

 

 

class B : A

{

        public void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

 

如果子类的方法是new进行声明的,父类也不能调用子类的方法,只能调用自己的方法,

class Program

{

        static void Main(string[] args)

        {

            A a = new B();

            a.Play();

 

            Console.ReadKey();

        }

}

 

class A

{

        public virtual void Play()

        {

            Console.WriteLine("父类说飞起来了");

        }

}

 

class B : A

{

        public new void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

★★★★★从上面的例子中可以看出,虽然父类指向了子类,但是子类没有进行override声明的话,不论父类有没有进行virtual的声明,最终调用的都是父类的方法。。。

 

子类用new进行方法的声明,那么子类的子类不能继承子类的方法。

class B : A

{

        public new void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

//class C : B {

//    public override void Play()

//    {

//        Console.WriteLine("子类的子类说飞起来了");

//    }

   

//}

(2.3)父类的方法用abstract进行声明,父类也必须用abstract进行声明,子类必须用override进行重写

声明为abstract的方法无法使用主体,类无法进行实例化

A a=new A();//这样写是错误的

abstract class A

{

        public abstract void Play();

}

 

 

class B : A

{

        public override void Play()  //子类必须用override进行重写

        {

            Console.WriteLine("子类说飞起来了");

        }

}

 

 

如果父类的方法是用private进行声明的,虽然子类也有该方法,但指向子类的父类对象,无法调用子类的方法。

class Program

{

        static void Main(string[] args)

        {

            A a = new B();

            a.Play();

            a.★★★★★由于父类的方法是private的,无法调用父类(咬)这个方法,也无法调用子类(咬)这个方法

 

            B b1 = new B();

            b1.咬();

 

            Console.ReadKey();

        }

}

 

public class A

{

        public virtual void Play()

        {

            Console.WriteLine("父类说飞起来了");

        }

 

        private void 咬() //父类的方法是用private 进行声明的

        {

            Console.WriteLine("A说了咬");

        }

}

 

 

class B : A

{

        public new void Play()

        {

            Console.WriteLine("子类说飞起来了");

        }

 

        public void 咬()

        {

            Console.WriteLine("B说了咬");

        }

}

 

 

 

小结:

(1)声明的对象都是先找到本类的方法,如果子类没有该方法的话,那么继承父类的方法,否则直接调用子类自己的方法。

 

(2)虽然父类指向了子类,但是子类没有进行override声明的话,不论父类有没有进行virtual的声明,最终调用的都是父类的方法。。。

 

(3)父类的方法用abstract进行声明,父类也必须用abstract进行声明,子类必须用override进行重写,除非没有子类。

声明为abstract的方法无法使用主体,类无法进行实例化

 

(4)父类的方法是private的,无法调用父类(咬)这个方法,也无法调用子类(咬)这个方法,也就是说父类不能是私有的方法,否则虽然父类指向了子类,也无法调用子类的方法。

 

(5)子类用new进行方法的声明,那么子类的子类不能继承子类的方法,不能进行方法的重写


————————————————委托的应用——————————————————◆◆35.委托

(1).如何声明一个委托?

delegate 返回值类型  委托类型(参数)

delegate void saydelegate(string s);

 

(2).委托是如何指向方法的?对方法进行调用

★★★委托类型声明的委托对象指向方法

★★★委托对象调用委托的方法(看方法的参数进行调用)

 

委托要调用方法,肯定要有方法被委托进行调用。

可以有以下两种方法进行调用

①委托类型   委托对象  实例化委托(传参数的名称即方法的名称)

saydelegate saydelegate =new saydelegate(Say); //先要指向方法

//saydelegate("123");                          //然后才能进行调用

 

 

②saydelegate saydelegate1 = Say;     //如果委托的对象没有指向方法,没有进行调用,缺少一步都不行。

//saydelegate("123");

 

 

(3).在方法里调用委托

①声明一个委托  delegate bool adelegate(int i); 委托的返回值类型,参数类型要和委托调用的方法返回值类型,参数类型一致

 

②声明一个委托调用的方法

static bool say(int i)

{

  return i > 20;

}

 

③在方法中进行调用委托

static List<int> list3(List<int> list1, adelegate f)

{

     List<int> list2 = new List<int>();

     foreach (int i in list1)

     {

        if (f(i))

        {

         list2.Add(i);

        }

 

      }

    

      return list2;

}

 

④代码中调用调用委托的函数

List<int> newList =list3(list1,say);

 

(4).简单的在代码中声明委托

①//声明一个委托

public delegate bool adelegate(string s);

 

②声明委托需要执行的方法

static bool Say(string s)

{

     if (s == string.Empty)

      {

        MessageBox.Show("请输入文本");

        return false;

      }

   

     else

      {

        return true;

      }

 

}

 

③在需要执行委托对象的声明

public adelegate adelegate1;

 

④在需要用委托调用方法的地方进行调用声明

adelegate1 = new adelegate(Say);

if (adelegate1(textBox1.Text.Trim()) == false)

{

  textBox1.Focus();

}

 

(5).委托的复杂应用

第一步:声明一个委托

public delegate void delegate1(A a);

 

第二步:在用户控件的事件时,进行调用

private void button1_Click(object sender, EventArgs e)

{

    if (adelegate != null)

   {

       A a = new A();

       a.value = textBox1.Text.Trim();

       a.isvalue = true;

       adelegate(a);

       if (a.isvalue == false)

     {

        MessageBox.Show("数据错误");

     }

  }

}

 

 

第三步:在窗体中进行监听,监听调用方法   在别的地方进行监听,如果听到,则把方法传给委托调用的方法。

Clientname.adelegate = Say; //把调用的方法传给委托调用的方法

 

第四步:声明监听的方法

void Say(A a)

{

    if (a.value.Length <= 2)

    {

      a.isvalue = false;

    }

}

 

 

(6).如何引入事件的概念

①那么存不存在清除监听和冒充监听呢?

 

第一步:声明委托

public delegate void adelegate();

 

第二步:在需要的地方执行委托

private void button1_Click(object sender, EventArgs e)

{

   if (adele != null)

   {

       adele();

   }

}

 

第三步:委托调用方法 控件名.委托对象

userName.adele +=new adelegate(Say);

userName.adele += new adelegate(Hellow);

 

 

第四步:声明委托调用的方法

void Say()

{

  MessageBox.Show("您好啊");

}

 

void Hellow()

{

  MessageBox.Show("hellow");

}

 

②清除监听

userName.adele = null;

③冒充监听

userName.adele(); //注意:如果清除监听后,则无法进行冒充监听

 

(7).既然是这样,那么如何防止清除和冒充监听呢,这里就引入了事件的概念。

第一种方法:

private adelegate _adele;

public event adelegate adele

{

  add

    {

      _adele += value;

           

    }

  

  remove

    {

      _adele -= value;

    }

}

 

进行调用的时候,内部

if (_adele != null)

{

   _adele();

 

}    外部的话,只能通过属性进行访问。因为字段是私有的,外部无法访问。

 

第二种方法:其实是微软给我们封装好的

public event adelegate adele;

 

(8).★★★★★要看事件对应的委托是什么,方法则声明为什么。

 

(9)小结:

委托的返回值类型,参数类型要和方法的返回值类型,参数类型一致。

委托可以直接把一个参数传递给方法,可以有返回值,也可以没有返回值。

class Program

{

    static void Main(string[] args)

    {

         List<int> list1 = new List<int>();

         list1.Add(10);

         list1.Add(20);

         list1.Add(-15);

         list1.Add(8);

         list1.Add(-20);

 

         adelegate adel = new adelegate(oushu);

         foreach (int i in list1)

         {

            if (adel(i))

            {

              Console.WriteLine(i);

            }

         }

            Console.ReadKey();

 

        }

 

        static bool oushu(int i)

        {

            return i > 10;

        }

    }

 

delegate bool adelegate(int i);

 

委托是一个类型,是把一个方法当做参数传递给另外一个方法。

class Program

{

   static void Main(string[] args)

  {

           List<int> list1 = new List<int>();

           list1.Add(10);

           list1.Add(20);

           list1.Add(-15);

           list1.Add(8);

           list1.Add(-20);

 

           List<int> newlist = list2(list1,oushu);

 

           foreach (int j in newlist)

           {

             Console.WriteLine(j);

           }

 

           Console.ReadKey();

 

   }

 

   static List<int> list2(List<int> list1,adelegate f)

    {

         List<int> list2 = new List<int>();

         foreach (int i in list1)

          {

            if (f(i))

             {

              list2.Add(i);

             }

              

          }

            return list2;

 

    }

 

   static bool oushu(int i)

     {

       return i > 10;

     }

}

 

delegate bool adelegate(int i);

 

 

 

 

——————————————————————lambda表达式———————————◆◆36.lambda表达式

(1). 检索出满足条件的

int[] value = { 10, 20, 5, 1, 18, -20 };

var e1 = value.Where(i => i > 10).OrderBy(i=>i);

foreach (int j in e1)

{

   Console.WriteLine(j);

}

 

(2).生成一个新的列表

int[] value = { 10, 20, 5, 1, 18, -20 };

var e1 = value.Select(i => i*20);

foreach (var j in e1)

{

   Console.WriteLine(j);

}

 

(3).生成一个带【】的列表

int[] value = { 10, 20, 5, 1, 18, -20 };

var e1 = value.Where(i => i > 10).OrderBy(i => i).Select(i => "[" + i + "]");

foreach (var j in e1)

{

    Console.WriteLine(j);

}

 

(4).运行效率更改的lambda表达式

int[] value = { 10, 20, 5, 1, 18, -20 };

 

var e1 = from i in value

            where i > 10

            orderby i descending

            select i*20;

 

 

foreach (var j in e1)

{

   Console.WriteLine(j);

}

 

 

 

 

 

————————————————正则表达式——————————————————◆◆37.正则表达式

 

 

 

 

 

 

 

◆◆38.扩展方法的应用

(1)扩展方法

什么样的类声明为static方法,就是没有用到任何的非static字段,属性。

static 不可以调用非static成员

 

(2)类上,方法上加上修饰符static.

static class StringHelper

{       public static bool IsEmail(this string s)

        {

            return s.Contains("@");

        }

 

        public static string Quoted(this string s)

        {

            return "[" + s + "]";

        }

}

(3)在第一个参数上加上this,第一个参数类型要是前面用到的类型。

 

(4)进行调用扩展

Console.WriteLine(s.IsEmail().ToHZ()); //其实就是相当于把前面的值以指定的类型传进来了

 

 

 

 

 

 

 

 

 

 

 

 

 

——————————————————线程———————————————————◆◆39.线程

(1)

//不安全的线程访问控件的类型

//Label.CheckForIllegalCrossThreadCalls = false;

 

(2)安全的访问控件的方式。

①声明一个委托

delegate void adelegate(string s);

adelegate adelegate1 = null;

 

②委托调用一个方法

adelegate1 = new adelegate(SetRan);

 

③创建一个方法,供委托进行调用

void SetRan(string s)

{

   label1.Text = s;

}

 

④声明线程

Thread thread1 = null;

 

⑤声明线程,开始线程的调用

ThreadStart ts = new ThreadStart(ran); //调用了ran这个方法

thread = new Thread(ts);

thread.Start();

 

⑥声明线程中要调用的方法

bool isStop = false;

void ran()

{

   while (!isStop)

   {

       Random ran = new Random();

       string s = ran.Next(10).ToString();

       this.Invoke(adelegate1, s); 调用这个方法的时候去执行委托,给委托进行传参数

       Thread.Sleep(200);

}

}

 

⑦结束线程

if (thread != null)

 thread.Abort();

———————————————————接口的使用———————————————

◆◆40.接口的简单使用

(1)声明一个接口

interface Comp

{

    bool Comp1(int i, int j);

}

(2)实现接口

class Incomp : Comp

{

   public bool Comp1(int i, int j)

   {

            return i > j;

 

   }

}

(3)委托传递方法名,接口传递实现接口的类名

static void Main(string[] args)

{

       List<int> list1 = new List<int>();

       list1.Add(10);

       list1.Add(20);

       list1.Add(30);

       list1.Add(-15);

 

       int j = list2(list1, new Incomp());//实例化一个类,把实现接口的类得对象传递过去

       Console.WriteLine(j);

       Console.ReadKey();

}

(4)static int list2(List<int> list1, Comp c)//接口的对象来接收实现接口的类得对象。

{

         int max = list1[0];

         List<int> list2 = new List<int>();

         foreach (int i in list1)

         {

            if (c.Comp1(max,i)) 接口的对象.接口实现的方法

            {

              max = i;

            }

 

         }

         return max;

 

}

       

 

posted @ 2011-04-18 11:03  冥海  阅读(376)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3