【1】C#基础:数据类型、运算、随机、枚举、结构、数组、列表、文件和文件流、序列化、MD5

本文介绍了C#编程的基础知识,包括控制台应用程序的创建、数据类型、流程控制、数组与集合的使用、文件操作等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、创建一个控制台应用程序。下面是在控制台输出一行,ReadKey是等待任意键再继续,如果没有这个的话,控制台会一闪而过,根本看不清输出的什么。还有个ReadLine就是等到用户输入,我们可以把用户输入的内容赋值给一个变量。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo_001
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World.");
            Console.ReadKey();
            Console.WriteLine("Hello too.");
            Console.ReadKey();
        }
    }
}

2、要排查语法错误的话,就点击“生成解决方案”,如果有错误的话,会罗列出来。

3、字体最好调整一下,比如换成Consolas,这种字体的好处就是,中英文的分号看的比较明显清楚。
这里写图片描述

4、养成给类和方法加注释的习惯,///快捷键。

5、数据类型。string/int/double/decimal/char/bool。存储金钱的用decimal,值后面加个mStringstring的区别见下图的颜色,String是一个类,是整个.net平台下的类,而stringC#的专有的数据类型关键字。当然在定义变量的时候尽量使用string
这里写图片描述

6、占位符的写法相当于格式化字符串,以及文件的IO操作,以及@可以简化对于转义字符的处理,不然对于路径这种就只能用\\来标识\了。格式化的时候,对于小数位数的操作如下,它会四舍五入。强制类型转换直接在被转换值前面加(类型)即可,比如(int)

static void Main(string[] args)
        {
            string name = "Eric";
            int age = 20;
            decimal money = 100.55m;
            File.WriteAllText(@"C:\Users\Eric\Desktop\test.txt", string.Format("my name is {0}, and age is {1}, and have money {2:0.0}", name, age, money));
        }

7、上面说的类型转换,需要注意,一般兼容的类型,可以用强制类型转换,但是如果不兼容的话,只能用Convert类来转换,如下。当然我们不能说只能用Convert,因为Convert的底层还是调用的各个数据类型的parse函数,即Convert.ToInt32(xxx)其实调用的是int.parse(xx),所以当然是后者效率高一点,我们今后可以直接用后者。
这里写图片描述

但是,我们还可以用如下的函数,因为上面的函数如果转换失败的话会抛出异常。下面的意思是,如果转换成功的话,就把转换后的复制给money,并且返回的结果是True。否则是False0

转换成字符串的是string s = age.ToString();

int money;
bool res = int.TryParse("123", out money);

8、逻辑运算符在C#中,是&&,||,!

9、流程控制的几个语句写的时候自己注意即可。if(){}else if(){}else{}try{}catch{}switch(){case xx:break;default:break;}while(){}do{}while();for(int i=x;i<x,i++){}for循环里如有break;就是跳出并结束当前整个循环体。continue;是结束本次循环,进入到下一次循环中。

10、调试。F11从开头一步步调试,我们一般是打断点,然后按F11一步步调试。

11、随机数。

Random rand = new Random();
int count = rand.Next(1,10);

12、常量的写法const int initMoney=100;之类的。

13、枚举一般声明在命名空间下面,这样所有的类都能用了,一般加上一个访问修饰符,声明和使用如下。一般枚举的第一个都是从0开始,后面依次跟上,当然我们也可以自定义从什么数字开始。

namespace demo_001
{
    public enum Status
    {
        online=2,
        offline,
        busy,
        available
    }
    class Program
    {
        static void Main(string[] args)
        {
            Status s = Status.available;
            Console.WriteLine(s);
            Console.ReadKey();
        }
    }
}

14、结构。

namespace demo_001
{
    public struct Person
    {
        public string name;
        public int age;
    }
    class Program
    {
        static void Main(string[] args)
        {
            Person p1;
            p1.name = "Eric";
            p1.age = 30;
        }
    }
}

15、数组和数组列表的区别。数组列表的实用好处主要2个,一是长度任意变化,二是里面可以放不同类型的数据。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo_001
{
    class Program
    {
        static void Main(string[] args)
        {
            double[] scores = { 60, 70, 80, 90 };
            Array.Sort(scores);
            Array.Reverse(scores);
            ArrayList ages=new ArrayList();
            ages.Add(30);
            ages.Sort();
            ages.Reverse();
            Console.WriteLine(scores.Length);
            Console.WriteLine(ages.Count);
            Console.ReadKey();
        }
    }
}

16、方法的一个细节是,如果我们返回的是同一个类型的数据的话,是可以用数组作为返回值的,但是如果返回多个而且是不同类型的呢?用out关键字来。

public void Test(int[] number, out int max, out int min, out double avg)
        {
            // 不需要return了,只需要在这里面给max/min/avg赋值即可,不赋值的话,报错。
        }

17、类的继承,是用:,不是extends之类的。

18、Hashtable本质上是键值对。这里一个细节需要注意:字符串用双引号,如果用单引号的话,会提示报错,因为单引号是用来char类型的,所以里面不能放太多字符。

static void Main(string[] args)
        {
            Hashtable h = new Hashtable();
            h.Add(1,"eric");
            h.Add(2,30);
            h.Add("gender","male");
            foreach(var item in h.Keys){
                Console.WriteLine(h[item]);
            }
            Console.ReadKey();
        }

19、Path类的几个方法。

static void Main(string[] args)
        {
            string path = @"C:\Users\Eric\Desktop\test.txt";
            Console.WriteLine(Path.GetFullPath(path));
            Console.WriteLine(Path.GetFileName(path));
            Console.WriteLine(Path.GetFileNameWithoutExtension(path));
            Console.WriteLine(Path.GetExtension(path));
            Console.WriteLine(Path.Combine(@"c:\Users\Eric\Desktop", "test.avi"));
            Console.ReadKey();
        }
result:
C:\Users\Eric\Desktop\test.txt
test.txt
test
.txt
c:\Users\Eric\Desktop\test.avi

20、File类的几个方法,CreateDeleteCopy等。文件的读取操作。

//字节读取方式
byte[] buffer1 = File.ReadAllBytes(@"C:\Users\Eric\Desktop\hello1.txt");
string s1 = Encoding.Default.GetString(buffer1);
Console.WriteLine(s1);
//字节写入方式
string s2 = "i am here.";
byte[] buffer2 = Encoding.Default.GetBytes(s2);
File.WriteAllBytes(@"C:\Users\Eric\Desktop\hello2.txt",buffer2);

//其他的只能处理文本文件内容,返回结果一个是数组,一个是字符串
string[] content1 = File.ReadAllLines(@"C:\Users\Eric\Desktop\hello1.txt", Encoding.Default);
            string content2 = File.ReadAllText(@"C:\Users\Eric\Desktop\hello1.txt", Encoding.Default);

//还有其他的,注意追加的那个函数AppendAllText
File.WriteAllText();
File.WriteAllLines();
File.AppendAllText();

以上介绍的文件类虽然使用方便,但是缺点是只能处理小文件,如果文件大的话,需要使用文件流。

21、现在用ArrayListHashTable的比较少,用List的比较多一些,原因在于拆箱装箱会影响效率。

// 这里的Add需要的是object对象参数,我们给了一个数值型数据,会自动装箱成对象,影响效率
ArrayList list1 = new ArrayList();
list1.Add(1);

// 这个不需要装箱,直接要的就是数值型数据
List<int> list2 = new List<int>();
list2.Add(1);

22、字典的用法以及遍历。

Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "Eric");
dict.Add(2, "Tom");
dict[3] = "Jerry";
foreach(var item in dict.Keys){
     Console.WriteLine(dict[item]);
}
foreach (KeyValuePair<int, string> kv in dict)
{
     Console.WriteLine(kv.Value);
}

23、文件流操作。同样也有多个类,其中有的类只能处理文本,有的可以处理多媒体文件。文件流打开的话需要关闭Close和处置掉Dispose,但是我们可以用using{}去省略这个。比如下面就是一个正常的打开读取一个文件,并且把这个文件里面的内容写入到另一个文件中,类似于复制。

        static void Main(string[] args)
        {
            string sourcePath = @"C:\Users\Eric\Desktop\hello1.txt";
            string targetPath = @"C:\Users\Eric\Desktop\hello3.txt";
            CopyFile(sourcePath, targetPath);
        }

        public static void CopyFile(string source, string target)
        {
            using(FileStream fsRead = new FileStream(source, FileMode.OpenOrCreate, FileAccess.Read))
            {
                using(FileStream fsWrite = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    // 就是一个字节数组,用来存取每次读取的文件流字节,但是因为我们自己写的代码,想规定每次读取多少,那就给这个字节数组定义多大的长度即可
                    byte[] buffer = new byte[1024];
                    // 循环读取
                    while (true)
                    {
                        // 游标停在上一次结束的地方,0意味着就从这边开始,读取多少长度字节放到buffer里面,既然是放在buffer里面,长度肯定最多只能是buffer的长度了,返回的是实际读取到的长度
                        int r = fsRead.Read(buffer, 0, buffer.Length);
                        // 一般读取不到的话,就返回0
                        if (r == 0)
                        {
                            break;
                        }
                        // 读取多少写多少长度r,写字节流也是,游标在上一次结束的位置,0意味着就从此开始,从buffer里面写r长度的内容到文件中,其实这个r就是本次buffer里面实际的内容长度
                        fsWrite.Write(buffer, 0, r);
                    }

                }
            }
        }

还有一对就是处理字符流的:

            using(StreamReader sr = new StreamReader(source, Encoding.Default))
            {
                using(StreamWriter sw = new StreamWriter(target))
                {
                    while(!sr.EndOfStream)
                    {
                        sw.WriteLine(sr.ReadLine());
                    }
                }
            }

24、序列化和反序列化,用于传输数据的。重写类输出的方法。

            using (FileStream fsWrite = new FileStream(@"C:\Users\Eric\Desktop\hello3.txt", FileMode.OpenOrCreate, FileAccess.Write))
            {
                Person p = new Person();
                p.name = "Tom";
                p.age = 30;
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fsWrite, p);
            }

            using(FileStream fsRead = new FileStream(@"C:\Users\Eric\Desktop\hello3.txt", FileMode.OpenOrCreate, FileAccess.Read))
            {
                BinaryFormatter bf = new BinaryFormatter();
                Person p = (Person)bf.Deserialize(fsRead);
                Console.WriteLine(p.name);
                Console.WriteLine(p.age);
            }

需要注意的是,序列化的对象要标记为可序列化,就是在类上面加个标签。

    [Serializable]
    public class Person
    {
        public string name { get; set; }
        public int age { get; set; }
        // 重写类输出的方法
        public override string ToString()
        {
            return this.name;
        }
    }

25、接口。接口和类的区别,要理解和应用。

26、MD5加密,。

        public static string GetCryptoPwd(string pwd)
        {
            // 创建一个md5对象
            MD5 md5 = MD5.Create();
            // 把要加密的字符串转成字节数组
            byte[] buffer = Encoding.Default.GetBytes(pwd);
            // 加密这个字节数组
            byte[] MD5Buffer = md5.ComputeHash(buffer);
            // 不能直接把结果转字符串,而是把字节数组里面的每一个元素转成字符串后拼接,而且这个转一定是转成16进制的
            string MD5Pwd = "";
            for (int i = 0; i < MD5Buffer.Length; i++)
            {
                // x标识转16进制,2标识每次转2位,高位用0补
                MD5Pwd += MD5Buffer[i].ToString("x2");
            }
            return MD5Pwd;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值