C#开发学习杂笔(更新中)

  • using相当于C中的include

  • C#中大小写敏感;

  • 最后一行写 Console.ReadKey(); 是针对 VS.NET 用户的。这使得程序会等待一个按键的动作,防止程序从 Visual Studio .NET 启动时屏幕会快速运行并关闭。

  • 与 Java 不同的是,文件名可以不同于类的名称。

  • namespace 相当于统一的一个包,里面包含了一系列的类class。

  • 隐式转换

byte b = 5;

int i = b;
int intValue = 42;

long longValue = intValue;

将一个较小范围的数据类型转换为较大范围的数据类型时,编译器会自动完成类型转换,这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。

  • 显式转换

指将一个较大范围的数据类型转换为较小范围的数据类型时,或者将一个对象类型转换为另一个对象类型时,需要使用强制类型转换符号进行显示转换,强制转换会造成数据丢失。

例如,将一个 int 类型的变量赋值给 byte 类型的变量,需要显示转换。

int i = 10;

byte b = (byte)i; // 显式转换,需要使用强制类型转换符号

或者

double doubleValue = 3.14;

int intValue = (int)doubleValue; // 强制从 double 到 int,数据可能损失小数部分
int intValue = 42;

float floatValue = (float)intValue; // 强制从 int 到 float,数据可能损失精度
int intValue = 123;

string stringValue = intValue.ToString(); // 将 int 转换为字符串

  • C# 内置的类型转换方法:
序号 方法 & 描述
1 ToBoolean 如果可能的话,把类型转换为布尔型。
2 ToByte 把类型转换为字节类型。
3 ToChar 如果可能的话,把类型转换为单个 Unicode 字符类型。
4 ToDateTime 把类型(整数或字符串类型)转换为 日期-时间 结构。
5 ToDecimal 把浮点型或整数类型转换为十进制类型。
6 ToDouble 把类型转换为双精度浮点型。
7 ToInt16 把类型转换为 16 位整数类型。
8 ToInt32 把类型转换为 32 位整数类型。
9 ToInt64 把类型转换为 64 位整数类型。
10 ToSbyte 把类型转换为有符号字节类型。
11 ToSingle 把类型转换为小浮点数类型。
12 ToString 把类型转换为字符串类型。
13 ToType 把类型转换为指定类型。
14 ToUInt16 把类型转换为 16 位无符号整数类型。
15 ToUInt32 把类型转换为 32 位无符号整数类型。
16 ToUInt64 把类型转换为 64 位无符号整数类型。

**这些方法都定义在 System.Convert 类中,使用时需要包含 System 命名空间。**它们提供了一种安全的方式来执行类型转换,因为它们可以处理 null值,并且会抛出异常,如果转换不可能进行。

注意点:

  • 隐式转换只能将较小范围的数据类型转换为较大范围的数据类型,不能将较大范围的数据类型转换为较小范围的数据类型;
  • 显式转换可能会导致数据丢失或精度降低,需要进行数据类型的兼容性检查;
  • 对于对象类型的转换,需要进行类型转换的兼容性检查和类型转换的安全性检查。

Parse 方法用于将字符串转换为对应的数值类型,如果转换失败会抛出异常。

string str = "123.45";

double d = double.Parse(str);

  • C# 内置类型转换方法的表格:
方法类别 方法 描述
隐式转换 自动进行的转换 无需显式指定,通常用于安全的类型转换,如从较小类型到较大类型
显式转换(强制转换) (type)value 需要显式指定,通常用于可能导致数据丢失或转换失败的情况
Convert 类方法 Convert.ToBoolean(value) 将指定类型转换为 Boolean
Convert.ToByte(value) 将指定类型转换为 Byte
Convert.ToChar(value) 将指定类型转换为 Char
Convert.ToDateTime(value) 将指定类型转换为 DateTime
Convert.ToDecimal(value) 将指定类型转换为 Decimal
Convert.ToDouble(value) 将指定类型转换为 Double
Convert.ToInt16(value) 将指定类型转换为 Int16(短整型)
Convert.ToInt32(value) 将指定类型转换为 Int32(整型)
Convert.ToInt64(value) 将指定类型转换为 Int64(长整型)
Convert.ToSByte(value) 将指定类型转换为 SByte
Convert.ToSingle(value) 将指定类型转换为 Single(单精度浮点型)
Convert.ToString(value) 将指定类型转换为 String
Convert.ToUInt16(value) 将指定类型转换为 UInt16(无符号短整型)
Convert.ToUInt32(value) 将指定类型转换为 UInt32(无符号整型)
Convert.ToUInt64(value) 将指定类型转换为 UInt64(无符号长整型)
Parse 方法 Boolean.Parse(string) 将字符串解析为 Boolean
Byte.Parse(string) 将字符串解析为 Byte
Char.Parse(string) 将字符串解析为 Char
DateTime.Parse(string) 将字符串解析为 DateTime
Decimal.Parse(string) 将字符串解析为 Decimal
Double.Parse(string) 将字符串解析为 Double
Int16.Parse(string) 将字符串解析为 Int16
Int32.Parse(string) 将字符串解析为 Int32
Int64.Parse(string) 将字符串解析为 Int64
SByte.Parse(string) 将字符串解析为 SByte
Single.Parse(string) 将字符串解析为 Single
UInt16.Parse(string) 将字符串解析为 UInt16
UInt32.Parse(string) 将字符串解析为 UInt32
UInt64.Parse(string) 将字符串解析为 UInt64
TryParse 方法 Boolean.TryParse(string, out bool) 尝试将字符串解析为 Boolean,返回布尔值表示是否成功
Byte.TryParse(string, out byte) 尝试将字符串解析为 Byte,返回布尔值表示是否成功
Char.TryParse(string, out char) 尝试将字符串解析为 Char,返回布尔值表示是否成功
DateTime.TryParse(string, out DateTime) 尝试将字符串解析为 DateTime,返回布尔值表示是否成功
Decimal.TryParse(string, out decimal) 尝试将字符串解析为 Decimal,返回布尔值表示是否成功
Double.TryParse(string, out double) 尝试将字符串解析为 Double,返回布尔值表示是否成功
Int16.TryParse(string, out short) 尝试将字符串解析为 Int16,返回布尔值表示是否成功
Int32.TryParse(string, out int) 尝试将字符串解析为 Int32,返回布尔值表示是否成功
Int64.TryParse(string, out long) 尝试将字符串解析为 Int64,返回布尔值表示是否成功
SByte.TryParse(string, out sbyte) 尝试将字符串解析为 SByte,返回布尔值表示是否成功
Single.TryParse(string, out float) 尝试将字符串解析为 Single,返回布尔值表示是否成功
UInt16.TryParse(string, out ushort) 尝试将字符串解析为 UInt16,返回布尔值表示是否成功
UInt32.TryParse(string, out uint) 尝试将字符串解析为 UInt32,返回布尔值表示是否成功
UInt64.TryParse(string, out ulong) 尝试将字符串解析为 UInt64,返回布尔值表示是否成功
  • System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。

int num;

num = Convert.ToInt32(Console.ReadLine());

示例:

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Module1
{
    internal class Demo4
    {
        public static void Main(string[] args)
        {
            int num;
            Console.WriteLine("请输入一个整数:");
            num = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("获取到的数为:" + num);
        }
    }
}
  • C# 转义序列码:
转义序列 含义
\\ \ 字符
\' ' 字符
\" " 字符
\? ? 字符
\a Alert 或 bell
\b 退格键(Backspace)
\f 换页符(Form feed)
\n 换行符(Newline)
\r 回车
\t 水平制表符 tab
\v 垂直制表符 tab
\ooo 一到三位的八进制数
\xhh . . . 一个或多个数字的十六进制数

字符常量是括在单引号里,例如,'x'

字符串常量是括在双引号 "" 里,或者是括在 @"" 里。

C# 支持的位运算符。假设变量 A 的值为 60,变量 B 的值为 13,则:

运算符 描述 实例
& 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 (A & B) 将得到 12,即为 0000 1100
| 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 (A | B) 将得到 61,即为 0011 1101
^ 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 (A ^ B) 将得到 49,即为 0011 0001
~ 按位取反运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0,包括符号位。 (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。
<< 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 A << 2 将得到 240,即为 1111 0000
>> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 A >> 2 将得到 15,即为 0000 1111
  • C# 支持的赋值运算符:
运算符 描述 实例
= 简单的赋值运算符,把右边操作数的值赋给左边操作数 C = A + B 将把 A + B 的值赋给 C
+= 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 C += A 相当于 C = C + A
-= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 C -= A 相当于 C = C - A
*= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 C *= A 相当于 C = C * A
/= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 C /= A 相当于 C = C / A
%= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C %= A 相当于 C = C % A
<<= 左移且赋值运算符 C <<= 2 等同于 C = C << 2
>>= 右移且赋值运算符 C >>= 2 等同于 C = C >> 2
&= 按位与且赋值运算符 C &= 2 等同于 C = C & 2
^= 按位异或且赋值运算符 C ^= 2 等同于 C = C ^ 2
|= 按位或且赋值运算符 C |= 2 等同于 C = C | 2

C# 支持的其他一些重要的运算符,包括 sizeoftypeof? :

运算符 描述 实例
sizeof() 返回数据类型的大小。 sizeof(int),将返回 4.
typeof() 返回 class 的类型。 typeof(StreamReader);
& 返回变量的地址。 &a; 将得到变量的实际地址。
* 变量的指针。 *a; 将指向一个变量。
? : 条件表达式 如果条件为真 ? 则为 X : 否则为 Y
is 判断对象是否为某一类型。 If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。
as 强制转换,即使转换失败也不会抛出异常。 Object obj = new StringReader("Hello"); StringReader r = obj as StringReader;

typeof 关键字用于获取一个类型的类型对象,它通常用于反射和动态创建类型实例。

下面是一个使用 typeof 的简单示例:

using System;

class Program

{

static void Main(string[] args)

{

Type type = typeof(string);

Console.WriteLine(type.FullName);

Console.ReadKey();

}

}

在上面的代码中,我们使用 typeof 关键字来获取 string 类型的类型对象,并将其存储在 Type 类型的变量 type 中,然后,我们使用 FullName 属性打印该类型的完全限定名。

当上面的代码被编译和执行时,它会产生下列结果:

System.String

  • foreach

C# 也支持 foreach 循环,使用 foreach 可以迭代数组或者一个集合对象。

简单点说就是可以用foreach 循环来遍历一个数组,例如下面的示例:

cs 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        //创建一个字符串列表
        List<string> myString = new List<string>();
        myString.Add("Google");
        myString.Add("Runoob");
        myString.Add("Taobao");

        int count = 0;
        foreach(string element in myString){
            count++;
            Console.WriteLine("Element #{0}:{1}", count, element);
        }
    }
}

输出:

cs 复制代码
Element #1:Google
Element #2:Runoob
Element #3:Taobao

当条件表达式不存在时,它被假设为真。但是一般情况下,程序员偏向于使用 for( ; ; ) 结构来表示一个无限循环。

C# 支持的访问修饰符如下所示:

  • public:所有对象都可以访问;
  • private:对象本身在对象内部可以访问;
  • protected:只有该类对象及其子类对象可以访问
  • internal:同一个程序集的对象可以访问;
  • protected internal:访问限于当前程序集或派生自包含类的类型。

C#当中,如果没有指定访问修饰符,则使用类成员的默认访问修饰符,即为 private 。如下代码中成员函数 GetArea() 声明的时候不带有任何访问修饰符,这个时候则默认当作采用private来修饰了。

cs 复制代码
using System;

namespace RectangleApplication
{
    class Rectangle
    {
        //成员变量
        internal double length;
        internal double width;

        double GetArea()
        {
            return length * width;
        }

        public void Display()
        {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    }

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle();
            rect.length = 30.01;
            rect.width = 999.66;
            rect.Display();
            Console.ReadKey();
        }
    }

}

数组是一个引用类型,所以需要使用 new 关键字来创建数组的实例。

cs 复制代码
double[] balance = new double[10];

数组是一种用于存储固定大小、同一类型元素的集合。理解 Array 类的特性和方法对于高效编写 C# 程序非常重要:

下表列出了 Array 类中一些最常用的属性:

属性名 说明 示例代码 输出
Length 获取数组中元素的总个数。 int[] arr = {1, 2, 3}; int length = arr.Length; 3
Rank 获取数组的维数(即数组的维度)。 int[,] matrix = new int[2, 3]; int rank = matrix.Rank; 2
IsFixedSize 判断数组的大小是否固定。 int[] arr = {1, 2, 3}; bool fixedSize = arr.IsFixedSize; true
IsReadOnly 判断数组是否为只读。 int[] arr = {1, 2, 3}; bool readOnly = arr.IsReadOnly; false
IsSynchronized 判断数组是否线程安全。 int[] arr = {1, 2, 3}; bool sync = arr.IsSynchronized; false
SyncRoot 获取用于同步数组访问的对象,通常用于多线程操作。 int[] arr = {1, 2, 3}; object syncRoot = arr.SyncRoot; syncRoot

C# Array 类 | 菜鸟教程

  • C# 中的构造函数

类的 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行。

构造函数的名称与类的名称完全相同,它没有任何返回类型。

默认的构造函数 没有任何参数。如果需要的话,一个带有参数的构造函数可以有参数,这种构造函数叫做参数化构造函数。这可以在创建对象的同时给对象赋初始值。

类的 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行。

析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。

析构函数用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载。

一般的来说,在代码里面的析构函数都不会被执行。你甚至看不到执行结果

  • 答疑点:

1、C#中使用了虚方法的继承和常规的继承有什么区别?

简单点说,就是虚方法允许派生类重写基类中的方法。通过在基类中使用 virtual 关键字声明方法,派生类可以使用 override 关键字来重写该方法。这种方式提供了更大的灵活性,因为派生类可以根据需要改变方法的行为。

反之,如果基类中的方法没有使用 virtual 关键字,派生类不能重写该方法。派生类只能隐藏(通过 new 关键字)基类的方法,但这并不会改变基类方法的行为。

2、

cs 复制代码
namespace OperatorOvlApplication44
{
    class Box
    {
        private double length;
        private double breath;
        private double height;

        public double getVolume()
        {
            return length * breath * height;
        }
        public void setLength(double len)
        {
            length = len;
        }
        public void setBreath(double bre)
        {
            breath = bre;
        }
        public void setHeight(double hei)
        {
            height = hei;
        }
        //重载+
        public static Box operator+ (Box b, Box c)
        {
            Box box = new Box();
            box.length = b.length + c.length;
            box.breath = b.breath + c.breath;
            box.height = b.height + c.height;
            return box;
        }
        //重载==
        public static bool operator == (Box lhs, Box rhs)
        {
            bool status = false;
            if(lhs.length == rhs.length && lhs.breath == rhs.breath
                && lhs.height == rhs.height)
            {
                status = true;
            }
            return status;
        }

    }
}

在上述的重载==,IDE为什么一直报红?

C# 要求如果你重载了 == 运算符,也必须重载 != 运算符。这是因为 ==!= 是逻辑上的对立操作,编译器会检查你是否同时重载了这两个运算符

相关推荐
QT 小鲜肉3 小时前
【个人成长笔记】Qt 中 SkipEmptyParts 编译错误解决方案及版本兼容性指南
数据库·c++·笔记·qt·学习·学习方法
一位代码3 小时前
python | requests爬虫如何正确获取网页编码?
开发语言·爬虫·python
A9better3 小时前
嵌入式开发学习日志41——stm32之SPI总线基本结构
stm32·单片机·嵌入式硬件·学习
看到我,请让我去学习3 小时前
Qt 控件 QSS 样式大全(通用属性篇)
开发语言·c++·qt
筱砚.4 小时前
【STL——vector容器】
开发语言·c++
mingupup4 小时前
WPF/C#:使用Microsoft Agent Framework框架创建一个带有审批功能的终端Agent
c#·wpf
lly2024064 小时前
数据访问对象模式(Data Access Object Pattern)
开发语言
std860214 小时前
Rust 与 Python – 这是未来的语言吗?
开发语言·python·rust
2503_930123934 小时前
Kubernetes (六)调度策略详解:从节点匹配到Pod调度全流程
java·开发语言