• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jk-2048
博客园    首页    新随笔    联系   管理    订阅  订阅
刘铁猛C#学习笔记5 操作符详解1
 
 

一.操作符的优先级

此表格中从上往下操作符优先级依次降低,上面的操作符优先级更高,更先运算
 

提升优先级的方法

可以通过加圆括号的方式,提高表达式的运算优先级
圆括号可嵌套
 

同优先级的运算顺序

同一行操作符运算优先级相同,优先级相同时大部分按照从左向右的顺序依次运算
但带有赋值功能的操作符固定为最晚运算,且同级运算顺序为从右向左
(把右边的值赋给左边)
 

常用简写方法

x += y; 等同于 x = x + y;
X -= y; 等同于 x = x - y;
 
例:
x += y += z;
因为+=是带有赋值功能的操作符,所以运算顺序是从右到左
先算 y += z
再算 x += y
当x = 100,y= 200 ,z = 300时
X += y += z运算后
结果x = 600,y = 500 , z = 300;
 

计算机操作符无结合律

3+4+5 只能理解为Add(Add(3,4),5),不能理解为Add(3,Add(4+5))
 

二.操作符的本质

操作符源自数学中的运算符
 

操作符的本质是对函数(算法)的简记法

加号“+”可以当作Add函数的简记
乘号“×”是对多次加法的简记
 

操作符不能脱离它关联的数据类型

例如程序中整型int的除法,只能得到整数类型int的答案(整除)
而double、float型数据除法得到的就是对应的double、float类型的小数
尤其C#是一种强类型语言
 

操作符简单定义

操作符可以说是一种与固定数据类型关联的一套基本算法的简记
可以为为自定义数据类型创建操作符
例:
 
先创建一个静态方法
static void Main(string[] args)
{
    Person person1 = new Person();
    Person person2 = new Person();
    person1.Name = "Deer";
    person2.Name = "Deer's wife";
    List<Person> nation = Person.GetMarry(person 1, person 2); //引用方法来初始化链表
    foreach (var p in nation)  //打印链表中的对象的Name
    {
        Console.WriteLine(p.Name);
    }
}

class Person
{
    public string Name;
    
    //创建返回值为一个person链表的方法“结婚”
    public static List<Person> GetMarry(person p1 , person p2)
    {
        List<Person> perple = new List<Person>();  //创建链表,名为“婚姻”
        people.Add(p1);    //将第一个人添加到链表中
        people.Add(p2);    //将第二个人添加到链表中
        for (int i = 0; i<11 , 1++)    //结婚以后生了11个孩子,这些孩子也添加到链表中
        {
            Person child = new Person();
            child.Name = p1.Name + "&" + p2.Name + "'s child";
            people.Add(child);
        }
        
        return people;
    }
}
 

三.用操作符定义和引用方法*

操作符是对方法的简记
所以静态函数”GetMarry”的创建还可以有如下的表示法
//使用操作符来定义方法
public static List<Person> operator +(person p1 , person p2)
    {
        List<Person> perple = new List<Person>();  //创建链表,名为“婚姻”
        people.Add(p1);    //将第一个人添加到链表中
        people.Add(p2);    //将第二个人添加到链表中
        for (int i = 0; i<11 , 1++)    //结婚以后生了11个孩子,这些孩子也添加到链表中
        {
            Person child = new Person();
            child.Name = p1.Name + "&" + p2.Name + "'s child";
            people.Add(child);
        }
        
        return people;
    }
引用方法时写为:
List<Person> nation = person1//使用操作符来引用方法

四.基本操作符

基本运算符用来组成基本表达式,基本表达式是是最简单的、不能再拆分的,用来组成其他表达式
所以基本运算符优先级最高,最先运算
 

1.成员访问操作符“.”

1.用来访问外层命名空间中的子集命名空间
2.用来访问命名空间中的类型
3.用来访问类型中的静态成员
4.用来访问对象的成员
 

2.方法调用操作符“f(x)”

与C/C++基本相同
f为函数名
x为参数
即使调用的函数没有参数,也不能省略括号
但在委托中添加方法时,不用写括号
 
 

3.元素访问操作符“[ ]”

访问C#数组

访问数组的元素
C#中的创建数组:
方法1 数组长度:
使用这种方法创建数组,创建后数组内有10个元素,且都会会被设为初始化的默认值0
方法2 初始化器:
编译器会自动数大括号内有几个数,就创建多大容量的数组实例
 
访问数组元素:同C/C++
数组的第一个元素下标为0,最后一个元素下标为N-1
数组类型的成员方法中,.Length可以得到数组的长度N
下标超出数组下标范围时编译会报错
 

访问C#字典

ex:一个类后面跟着尖括号"< >"说明这个类是泛型类,之后会讲
 
创建字典并初始化:
string为这个泛型类的索引类型,student为泛型类的值类型
可以通过索引找到值(哈希表?)
已知索引,访问值:在方括号中写要访问的索引,在这个例子中索引为string类型
 

4.自增自减操作符“++”、“--”

前置自增x++

x++:变量X的值变为X+1,而x++这个表达式的值为X
后置自增操作符是先赋值再自增
x--同理

后置自增++x

赋值运算顺序与前置相反
前置自增操作符是先自增再赋值
--x同理
 

5.typeof 查看类型的内部结构

类型的内部结构:metadata,元数据
Type t = typeof(int);            //定义类型t为类型int的内部结构
Console.WriteLine(t.Namespace);  //打印int的命名空间名字
Console.WriteLine(t.FullName);   //打印int类型带命名空间的名字
Console.WriteLine(t.Name);       //打印int类型不带命名空间的名字
int c = t.GetMethods().Length;   //c = int类型中成员方法的数量

//GetMethods()方法返回的是一个方法数组
foreach (var mi in t.GetMethods())
{
    Console.WriteLine(mi.Name);  //打印int类型包含的所有方法名
} 

6.default 获取类型默认值

(1)结构体类型(值类型)

int x = default(int);   //获取int类型的默认值,是零
double x = default(double);  //获取double类型的默认值,也是零

(2)引用类型

Form myForm = default(Form);  
//获取Form类型的默认值,是一个内存中全刷成零的Form对象,就是NULL值
引用类型的默认值为NULL

(3)枚举类型

enum Level   //声明一个枚举类型
{
    Low,
    Mid,
    High
}
Level level = default(Level);
Console.WriteLine(level);  //打印
结果为Low
枚举类型的默认值为声明时的第一个值
类似数组的第一个元素
 
但声明时给枚举类型进行了显性的赋值时
enum Level   //声明一个枚举类型
{
    Low = 1,
    Mid = 0,
    High = 2
}
此时打印结果为Mid
声明时进行了赋值时,枚举类型的默认值为赋值为0的值
 

7.new 创建实例调用构造器

var关键字

来源于单词Variable ,可变类型
Int x; 显式类型变量
var x; 隐式类型变量 “我给他赋值的时候,程序你自己看着办”
x = 100;时,x类型被定为int
x = 100f;时,x的类型被定为float
C#是强类型语言,var变量的类型一旦被赋值确定,类型就不能再改变
var变量的类型由第一次赋值决定,之后不能再改变
 

new操作符主要功能

创建一个类型的实例,并马上调用该类型的实例构造器
Form myForm = new Form();  //创建实例并调用构造器,然后将实例地址赋值给引用变量
还能获得创建的实例的内存地址,并通过“=”赋值给访问这个实例的引用变量
 

附加功能

(1)调用实例的初始化器
Form myForm = new Form() { Text = "Hello" , FormBorderStyle = FormBorderStyle.SizableTooWindow};
在大括号内给实例的成员变量初始化赋值,可同时初始化多个成员变量
 
(2)同时使用成员访问操作符
new Form().ShowDialog();
可以运行并显示,只是创建的实例因为没有引用变量引用,之后会被C#垃圾收集器销毁
可用于访问一次性对象
 
(3)不同new创造实例的例子
string是一个类(class)类型,但使用时不用创建实例
因为string过于常用,是一个基本类型,C#对其开了一个语法糖衣,隐藏了自动的new操作符
手动用new操作符创建实例也是可以的
 
整型数组
Int [ ] myArray = { 1, 2, 3, 4, };
整型数组用大括号初始化时,不用new创建实例,这也是一个语法糖衣
 
(4)为匿名类型创建实例
var person = new {Name = "JK" , Age = 19 };

Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
即使没有手动创建有名字的类型,这个程序也可以使用
程序会自动创建匿名的、成员包含Name、Age字段的泛型类型
由此可见var关键字在泛型领域可大展拳脚
 

危险警告

一旦在一个类中调用了new操作符,会使这个类与用new创建实例的类型产生非常紧密的耦合
(紧耦合)
ex:参见【设计模式】-【依赖之路】,可以学习如何将紧耦合变为相对宽松的耦合
 

new关键字的其他用途

(1)当作操作符来使用
(2)子类对父类方法的隐藏
class Student   //父类
{
    public void Report()
    {
        Console.WriteLine("I'm a student");
    }
}

class CsStudent: Student  //继承自父类的子类
{
    new public void Report()
    {
        Console.WriteLine("I'm CS student");
    }
}
new关键字,作为修饰符使用在子类的实例方法前,该方法与父类中的方法头完全一致
此时会隐藏父类的方法,子类用该方法名调用时使用子类自己的方法
 
posted on 2024-02-23 18:48  JK降谷羽  阅读(86)  评论(1)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3