c#记录三


字符串string

主要是对string类的一些主要操作方法


static void Main(string[] args)
{
    //使用string类型存储字符串类型,字符串用双引号引起来
    string s = "www.baidu.com";

    //Length属性
    int sLength = s.Length;//Length返回字符串长度,就是获取该字符串有多少个字符,空格也属于一个字符
    Console.WriteLine(sLength);

    //比较字符串是否相等
    string s1 = "www.baidu1.com1";
    Console.WriteLine(s1 == s);//输出False

    //字符串连接,直接使用+
    s = "http://" + s;
    Console.WriteLine(s);

    //使用类似索引器访问字符串某个字符
    Console.WriteLine(s[10]);

    //遍历字符串所有字符
    for(int i=0;i<s.Length;i++)
    {
        Console.WriteLine(s[i]);
    }

    //比较字符串,CompareTo,当两个字符串相同的时候,返回0 ,当s在字母表中靠前的时候,返回-1,否则返回1
    int res = s.CompareTo("wwe");
    Console.WriteLine(res);

    //替换,Replase('.','-')把指定的字符换成指定的字符,或者把指定的字符串换成指定的字符串
    Console.WriteLine(s);
    string newStr = s.Replace('.', '-');
    Console.WriteLine(newStr);
    string newStr1 = s.Replace("www", "bbb");
    Console.WriteLine(newStr1);

    //split方法,切割
    string[] strArray = s.Split('.');
    foreach(string temp in strArray)
    {
        Console.WriteLine(temp);
    }

    //截取 Substring(index,length);//从索引index开始,截取length长度,如果length没有,就一直到结尾
    string sSub = s.Substring(3, 7);
    Console.WriteLine(sSub);

    //ToUpper(),ToLower();Trim()//删除首尾空白

    //IndexOf(string)//查找字符串,是否包含子字符串,并返回开始索引,不存在返回-1
    Console.WriteLine(s.IndexOf("dev"));

    Console.ReadKey();
}

StringBuilder

一、StringBuilder类是位于System.Text命名空间下
二、和string类的区别在于:string字符串是不可变的,string类型每次改变其实是创建了一个新的,然后复制过去,旧的就删除了;而StringBuilder 创建的字符串是可变的
三、所以如果对字符串会进行频繁的增加,删除等改变操作的时候,StringBuilder的效率会高很多,因为不会频繁的对内存进行操作

    class Program
    {
        static void Main(string[] args)
        {
            //一、利用构造函数创建StringBuidler
            StringBuilder sb = new StringBuilder("www.baidu.com");
            //二、初始一个空StringBuilder对象,占有20个字符的大小
            StringBuilder sb1 = new StringBuilder(20);
            //三、初始化一个占有100个字符大小的字符串,并赋给一定的字符
            StringBuilder sb2 = new StringBuilder("www.baidu.com", 100);

            //Append(),添加
            Console.WriteLine(sb2);
            sb2.Append("/xxx.html");
            Console.WriteLine(sb2);

            //Insert(),在指定位置插入字符串
            sb2.Insert(3, "wangzhipeng");
            Console.WriteLine(sb2);

            //Remove(index,length),表示从index开始移除length长度的字符串
            sb2.Remove(3, 11);
            Console.WriteLine(sb2);

            //Replace,替换字符或者字符串
            sb2.Replace('.', '-');
            Console.WriteLine(sb2);
            sb2.Replace("www", "abc");
            Console.WriteLine(sb2);


            Console.ReadKey();
        }
    }

正则表达式

正则表达式是当需要对字符串进行匹配操作的时候,比如说,匹配一段字符串是否是只有数字和字母;匹配一段字符串是否按照规定是指定的长度内存储的是指定的内容。
如果只判断字符串是不是都是数字,可以通过循环判断,但是对于复杂的字符串用循环判断就复杂了。这时候就用到正则表达式。
具体操作见代码:

class Program
    {
        static void Main(string[] args)
        {
            string s = "I am blue cat";
            //搜索字符串,符合正则表达式的情况,然后把所有符合的位置替换成后面的字符串
            //定位元字符,^ 定位开始位置
            string newS = Regex.Replace(s, "^", "开始:");
            Console.WriteLine(newS);

            //定位元字符,$ 定位结束位置
            string newS1 = Regex.Replace(s, "$", ":结束");
            Console.WriteLine(newS1);

            //校验密码是否都是数字
            //string sCheck1 = Console.ReadLine();
            string sCheck1 = "123123";

            //方法一:for循环遍历,判断
            bool isMatch = true;//默认标志位,表示是合法密码
            for(int i=0;i<sCheck1.Length;i++)
            {
                if (sCheck1[i] < '0' || sCheck1[i] >'9')
                {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch)
            {
                Console.WriteLine("合法密码");
            }
            else
            {
                Console.WriteLine("不合法密码");
            }
//方法二:正则表达式
//元字符
            //. 匹配除换行符以外的任意字符
            //\w 匹配字母、数字、下划线、汉字 (指大小写字母、0-9的数字、下划线_)
            //\W \w的补集  ( 除“大小写字母、0-9的数字、下划线_”之外)
            //\s 匹配任意空白符    (包括换行符/n、回车符/r、制表符/t、垂直制表符/v、换页符/f)
            //\S \s的补集  (除\s定义的字符之外)
            //\d 匹配数字   (0-9数字)
            //\D 表示\d的补集    (除0-9数字之外)
            //在正则表达式中,\是转义字符. * 是元字符 如果要表示一个\ . *字符的话,需要使用\\ \. \*

            isMatch = true;
            string pattern = @"^\d*$";//正则表达式,表示规则是一个数字字符串
            //^/d表示,以/d(数字0-9)开头,*表示一个或多个字符
            isMatch =  Regex.IsMatch(sCheck1, pattern);
            if (isMatch)
            {
                Console.WriteLine("合法密码");
            }
            else
            {
                Console.WriteLine("不合法密码");
            }
//反义字符
            /*
                \W  \w的补集   ( 除“大小写字母、0 - 9的数字、下划线_”之外)
                \S  \s的补集(除\s定义的字符之外)
                \D 表示\d的补集(除0 - 9数字之外)
                \B 匹配不是单词开头或结束的位置
                [ab]    匹配中括号中的字符
                [a - c]   a字符到c字符之间是字符
                [^ x]    匹配除了x以外的任意字符
                [^ adwz] 匹配除了adwz这几个字符以外的任意字符
            */
            string strFan = "I am a cat.";
            string patternStrFan = @"[^ahou]";
            string afterFan = Regex.Replace(strFan, patternStrFan,"*");//把除了正则表达式内的字符,都转换成*
            Console.WriteLine(afterFan);

//重复描述字符
            /*
                {n}     匹配前面的字符n次
                {n,}    匹配前面的字符n次或多于n次
                {n,m}   匹配前面的字符n到m次
                ?   重复零次或一次
                +   重复一次或更多次
                *   重复零次或更多次
             */
            string qq = "845294141";
            string qq2 = "qq986995057";
            string qq3 = "123123123123123";
            string patternQQ = @"^\d{5,12}$";//重复\d5-12次
            Console.WriteLine(Regex.IsMatch(qq, patternQQ));//IsMatch表示,只有有自字符合法就可以
            Console.WriteLine(Regex.IsMatch(qq2, patternQQ));
            Console.WriteLine(Regex.IsMatch(qq3, patternQQ));

//择一匹配
            // |    将两个匹配条件进行逻辑“或”(Or)运算。
            //输出字母和数字
            string getOne = "34 ( ) asdf* 阿萨德价格";
            string patternGetOne = @"\d|[a-z]";//表示/d或者[a-z]
            MatchCollection col = Regex.Matches(getOne, patternGetOne);
            foreach(Match match in col)
            {
                Console.WriteLine(match.ToString());
            }
            //输出人名
            string name = "zhangsan;lisi,wangwu.zhaoliu";
            string patternName = @"[;,.]";
            string[] res = Regex.Split(name, patternName);
            foreach(string temp in res)
            {
                Console.WriteLine(temp);
            }
            //使用择一匹配输出
            string patternName1 = @"[;]|[,]|[.]";
            string[] res1 = Regex.Split(name, patternName1);
            foreach (string temp in res1)
            {
                Console.WriteLine(temp);
            }

            //重复多个字符使用(abcd){n}进行分组限定
            string strInput = "abdfabdfab12ab__alksjdfabasdflj";
            string strGroup = @"(ab\w{2}){2}";// == "ab\w{2}ab\w{2};
            Console.WriteLine(Regex.Replace(strInput, strGroup,"5555"));

            //检测IP地址是否合法

            /*
             * IP地址为:0-255.0-255.0-255.0-255
             * 2 0-4 0-9  百位为2,十位0-4,个位0-9
             * 2 5 0-5
             * 0-1 0-9 0-9
             * @"^(((
             * 2[0-4]\d             2 0-4 0-9情况
             * |
             * 25[0-5]              2 5 0-5情况
             * |
             * [01]?\d\d?)          ?表示前面的有零次或者1次,实现ip是二位或者一位树的运算
             * \.                   就表示.
             * )
             * {3}                  实现***.***.***.三次
             * (2[0-4]\d|25[0-5]|[01]?\d\d?))$
            */
            string regexStrIp4 = @"^(((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?))$";
            Console.WriteLine("请输入一个IP4地址:");
            string inputStrIp4 = Console.ReadLine();
            Console.WriteLine(inputStrIp4 + " 是否为合法的IP4地址:" + Regex.IsMatch(inputStrIp4, regexStrIp4));
            Console.WriteLine("请输入一个IP4地址:");
            string inputStrIp4Second = Console.ReadLine();
            Console.WriteLine(inputStrIp4 + " 是否为合法的IP4地址:" + Regex.IsMatch(inputStrIp4Second, regexStrIp4));

            Console.ReadKey(); 
        }
    }

委托

记录一中也有委托的相关概念,但仅仅是对委托赋一个方法名,进行引用,没有其他的操作。
这里会再介绍一些委托的方法,包括:
一、委托创建实例的两种方法:
1、通过new关键字
2、直接赋值
二、委托调用的两种方法:
1、变量后+括号
2、Invoke方法
三、委托作为参数进行传递

    class Program
    {
        //定义一个委托类型,名字叫GetAString,返回值是string类型,参数为空
        //编译器会把这个委托当作类处理
        private delegate string GetAString();
        static void Main(string[] args)
        {
            int x = 40;
            string xTs = x.ToString();//ToString()用来把数据转换成字符串
            Console.WriteLine(xTs);

            //委托类型创建实例方法一:通过new关键字
            //ToString没有带括号,只是把ToString引用一下
            //a就指向了x.ToString方法
            GetAString a = new GetAString(x.ToString);//引用类的普通方法
            //委托类型实例调用方法一:直接变量后+括号
            string xTs1 = a();
            Console.WriteLine(xTs1);
            //委托类型创建实例方法二:直接把方法赋值给委托类型变量
            GetAString b = x.ToString;
            //委托类型实例调用方法二:Invoke方法
            string xTs2 = a.Invoke();
            Console.WriteLine(xTs2);

            //委托类型作为参数传递
            PrintString method = Method1;//需要先初始化
            PrintStr(method);
            method = Method2;
            PrintStr(method);

            Console.ReadKey();
        }

        //委托类型做为参数传递
        private delegate void PrintString();
        static void PrintStr(PrintString print)
        {
            print();
        }
        static void Method1()//静态方法
        {
            Console.WriteLine("Method1");
        }
        static void Method2()
        {
            Console.WriteLine("Method2");
        }
    }

Action委托

除了我们自己定义委托之外,还可以调用系统自带的委托,下面介绍Action委托

//Action是系统内置(预定义)的委托类型
//Action只能指向没有返回值,参数可以有可以没有
//参数通过泛型控制Actiong<int,string,bool....>最多可以带有16个参数,参数类型必须对应
    class Program
    {
        static void PrintStr()
        {
            Console.WriteLine("helloworld");
        }
        static void PrintInt(int num)
        {
            Console.WriteLine(num);
        }
        static void PrintInt(int num1,int num2)
        {
            Console.WriteLine(num1 + num2);
        }
        static void Main(string[] args)
        {
            //一、使用Action指向一个无参数,无返回值类型的方法
            int x = 100;
            Action a = PrintStr;
            a();

            //二、使用Action指向无返回值,有一个参数的方法
            Action<int> b = PrintInt;
            b(10);

            //三、使用Action指向无返回值,多个参数的方法
            //如果有重载方法,系统会自动匹配
            Action<int, int> c = PrintInt;
            c(10, 10);
            Console.ReadKey();
        }
    }

Func委托

上面Action委托是没有返回值的自带的委托,当然也有必须要有返回值的委托,就是Func委托
参数依然是0-16个之间,参数类型也需要对应,在泛型里面,最后一个代表返回值类型,前面的都代表参数类型

 class Program
    {
        static int Test1()
        {
            return 1;
        }
        static int Test2(string str)
        {
            return str.Length;
        }
        static int Test3(string str,int num)
        {
            return num + str.Length;
        }
        static void Main(string[] args)
        {
            //一、只有返回值类型,没有参数类型
            Func<int> a = Test1;//泛型中指定的是返回值类型
            Console.WriteLine(a());

            //二、带有返回值类型和一个参数类型
            Func<string, int> b = Test2;//泛型中,最有一个类型表示返回值类型,前面的表示参数类型
            Console.WriteLine(b("ASDFASDFASDF"));

            //三、带有int返回值类型和两个参数类型(string,int)
            Func<string, int, int> c = Test3;
            Console.WriteLine(c("asdf", 12));

            Console.ReadKey();
        }
    }

多播委托

//多播委托,是委托指向多个方法
//添加什么顺序,调用就是什么顺序
//如果有返回值,返回的是最后一个委托的方法的结果
//当委托没有指向方法的时候就调用,会出现异常
//如果多播委托某个发生异常,整个过程停止。
class Program
    {
        static void Test1()
        {
            Console.WriteLine("test1");
        }
        static void Test2()
        {
            Console.WriteLine("test2");
        }
        static void Main(string[] args)
        {
            //多播委托,是委托指向多个方法
            Action a = Test1;
            //+委托
            a += Test2;
            a();
            //-委托
            a -= Test1;
            a();


            Console.WriteLine();
            //取得多播委托中所有的方法的委托
            a += Test2;
            a += Test1;
            Delegate[] delegates = a.GetInvocationList();
            foreach(Delegate d in delegates)
            {
                d.DynamicInvoke();
            }
            Console.ReadKey();
        }
    }

匿名方法

//本质上还是方法,只是没有名字
//任何使用委托变量的地方,都可以使用匿名方法赋值
namespace 匿名方法
{
    class Program
    {
        //Test1是有名字的方法
        static int Test1(int a,int b)
        {
            return a + b;
        }
        static void Main(string[] args)
        {
            Func<int, int, int> plus = Test1;
            //将上述修改成匿名方法的形式
            Func<int, int, int> plus1 = delegate (int arg1, int arg2)
            {
                return arg1 + arg2;
            };
            //匿名方法只能赋值给委托去调用,不需要在其他地方调用
            //一般用在回调函数中
            Console.WriteLine(Test1(1, 2));

            Console.ReadKey();
        }
    }
}

Lambda表达式

//Lambda就是用来替代匿名方法的,所以Lambda表达式也是定义方法
namespace Lambda表达式
{
    class Program
    {
        static void Main(string[] args)
        {
            //下面是匿名方法
            Func<int, int, int> plus = delegate (int arg1, int arg2)
            {
                return arg1 + arg2;
            };
            //用Lambda表达式表示,参数不需要声明类型
            //=>左边列出参数,右边是函数体
            Func<int, int, int> plus1 = (arg1, arg2)=>
            {
                return arg1 + arg2;
            };
            Console.WriteLine(plus1(1, 2));

            //如果只有一个参数,不需要括号
            Func<int, int> test2 = a => { return a; };
            Console.WriteLine(test2(3));

            //如果函数体只有一句,不需要大括号
            Func<int, int> test3 = a => a + 1;
            Console.WriteLine(test3(3));

            //访问外部的变量
            int somVal = 5;
            Func<int, int> f = x => x + somVal;
            Console.WriteLine(f(3));
            somVal = 7;
            Console.WriteLine(f(3));
            Console.ReadKey();
        }
    }
}

事件

//事件只能作为类成员声明
//声明加上关键词event,基于委托,是一种特殊的委托,发布订阅机制
//使用和委托相似
//个人感觉:类似于QT中的信号和槽
namespace _011_事件
{
    class Program
    {
        public delegate void MyDelegate();
        public MyDelegate mydelegate;//声明委托类型变量作为类成员
        public event MyDelegate myevent;//声明事件
        static void Main(string[] args)
        {
            Program p = new Program();
            p.mydelegate = Test1;
            p.mydelegate();
            p.myevent = Test1;
            p.myevent();

            Console.ReadKey();
        }
        static void Test1()
        {
            Console.WriteLine("Test1");
        }
    }
}

对事件的使用,观察者模式

//有一个被观察者:
//多个观察者:观察被观察者的状态变化
//当被观察者发生状态变化,观察者就会做相应的事情
//相当于QT中信号和槽的关系
//不要因为观察者的变化去修改被观察者里面的代码

首先有被观察者:Cat类

class Cat
    {
        private string name;
        private string color;
        public Cat(string name,string color)
        {
            this.name = name;
            this.color = color;
        }
        /// <summary>
        /// 猫进屋,(被观察者状态发生改变)
        /// </summary>
        public void CatComming(Mouse mouse1,Mouse mouse2)
        {
            Console.WriteLine(color + "猫" + name+"过来了,喵喵喵...");
            mouse1.RunAway();
            mouse2.RunAway();
        }
        public void CatEat()
        {
            Console.WriteLine(color + "猫" + name + "吃东西,喵喵喵...");
            if(catEat!=null)
            {
                catEat();
            }
        }

        public void CatCommingNow()
        {
            Console.WriteLine(color + "猫" + name + "过来了,喵喵喵...");
            if(catCome !=null)
            {
                catCome();
            }
        }

        public Action catCome;//声明一个委托,让观察者去注册,这个时候可以通过cat对象去调用,可能发生问题
        public event Action catEat;//防止外接调用,加入event,事件不能在类的外部触发,只能在类内部触发,但可以在外部注册
    }

然后再来一个观察者,mouse类

class Mouse
    {
        private string name;
        private string color;
        public Mouse(string name,string color,Cat cat)
        {
            this.name = name;
            this.color = color;
            cat.catCome += this.RunAway;//减少每次增加观察者都注册一下的操作
        }
        public void RunAway()
        {
            Console.WriteLine(color + "的老鼠" + name + "逃跑了...吱吱吱");
        }

        public void Happy()
        {
            Console.WriteLine(color + "的老鼠" + name + "很开心...吱吱吱");
        }
    }

观察者和被观察者结合

    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat("加菲猫", "黄色");
            cat.catCome();//这是个委托,可以外部调用,但是很危险;最好改成事件
            Mouse mouse1 = new Mouse("米奇", "黑色",cat);
//            cat.catCome += mouse1.RunAway;比较繁琐,直接修改Mouse的构造函数,增加参数
            Mouse mouse2 = new Mouse("唐老鸭", "红色",cat);
//            cat.catCome += mouse1.RunAway;
            //cat.CatComming(mouse1,mouse2);//猫的状态发生改变,发送一个消息,让观察者接收后决定动作
            //上一行,在cat中调用了观察者的方法,当观察者发生改变的时候,要同时修改被观察者的代码,耦合性太高
            cat.CatCommingNow();

            Console.ReadKey();

        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值