C#操作符

操作符概览

  • 操作符(operator)也称为运算符
  • 操作符是用来操作数据的,被操作符操作的数据成为操作数(operand)。
  • 操作符对一系列称为操作数的值或变量,执行数学或逻辑运算来生成新值(结果)。
操作符

操作符本质

  • 操作符的本质是对函数(即算法)的“简记法”。
  • 操作符不能脱机与其关联的数据类型,操作符就是固定数据类型相关联的一套基本算法的“简记法”。
using System;
using System.Collections.Generic;

namespace TestApp
{
    class User
    {
        public string UserName;
        public static List<User> operator +(User u1, User u2)
        {
            List<User> users = new List<User>();
            users.Add(u1);
            users.Add(u2);

            for (int i = 0; i < 10; i++)
            {
                User child = new User();
                child.UserName = u1.UserName + "&" + u2.UserName + "'s child";
                users.Add(child);
            }

            return users;
        }
    }
    class Program
    {   
        static void Main(string[] args)
        {
            User u1 = new User();
            u1.UserName = "John";
            User u2 = new User();
            u2.UserName = "Mary";

            List<User> list = u1 + u2;
            foreach(var item in list)
            {
                Console.WriteLine(item.UserName);
            }
            Console.ReadLine();
        }  
    }
}

操作符优先级

  • 使用圆括号()提高被括起来的表达式的优先级
  • 圆括号()可以被嵌套
  • C#语言中[]{}有专门的用途

同级操作符运算顺序

  • 除了带有赋值功能的操作符,同优先级操作都是从左向右进行运算。
  • 带有赋值功能的操作符的运算顺序是从右向左
  • 与数学运算不同,计算机语言的同优先级运算没有“结合率”。

基本操作符

成员访问操作符.

System.ID.File.Create("C:\\test.txt");

// 访问外层命名空间的子集命名空间
System.ID
// 访问命名空间的类型
System.ID.File
// 访问类型的静态类型
System.ID.File.Create

方法调用操作符()

// Basic语言中如方法无参数则可省略圆括号
 Console.WriteLine("test");

使用委托时可不带方法调用操作符

using System;

namespace TestApp
{
    class Calculator
    {
        public static void Print()
        {
            Console.WriteLine("test");
            Console.ReadKey();
        }
    }
    class Program
    {   
        static void Main(string[] args)
        {
            //创建委托并管理Calculator类的Print方法
            Action action = new Action(Calculator.Print);
            //执行委托
            action();
        }  
    }
}

元素访问操作符[]

  • 访问数组的元素
int[] intArr = new int[4] { 1, 2, 3, 4};
Console.WriteLine("{0} {1}", intArr[0], intArr[intArr.Length-1]);
Console.ReadKey();
  • 访问字典的元素
using System;
using System.Collections.Generic;

namespace TestApp
{
    class User
    {
        public uint UserID;
        public string UserName;
    }  
    class Program
    {   
        static void Main(string[] args)
        {
            Dictionary<string, User> dict = new Dictionary<string, User>();
            for(int i=0; i<100; i++)
            {
                string name = "user" + i.ToString();

                Random rd = new Random();
                int number = rd.Next(10000, 999999);

                User user = new User();
                user.UserID = Convert.ToUInt32(number);
                user.UserName = name;

                dict.Add(name, user);
            }

            User u = dict["user1"];
            Console.WriteLine("{0} {1}", u.UserID, u.UserName);
            Console.ReadKey();
        }  
    }
}

自增自减操作符++ --

int x = 100;
int y = x++;
Console.WriteLine("{0} {1}", x, y);//100 101
Console.ReadKey();

类型操作符 typeof

//Metadata
Type t = typeof(int);
Console.WriteLine("namespace: {0}\nfullname: {1}\nname: {2}\n", t.Namespace, t.FullName, t.Name, t.Name);

int count = t.GetMethods().Length;
foreach(var item in t.GetMethods())
{
    Console.WriteLine(item.Name);
}
Console.WriteLine("method count : {0}", count);

Console.ReadKey();

获取类型默认值 default

  • 结构体 默认自为0
int i = default(int);
Console.WriteLine("default value is {0}", i);
Console.ReadKey();
  • 引用类型默认值为null
  • 枚举类型
using System;

namespace TestApp
{
    enum Level
    {
        Low = 100,
        Middle = 200,
        High = 300
    }
    class Program
    {   
        static void Main(string[] args)
        {
            Level l = default(Level);
            Console.WriteLine(l);//0
            Console.ReadKey();
        }  
    }
}

创建实例 new

new运算符的作用是在内存中创建实例,并调用实例的构造器。

//隐式变量声明
var x = 100L;
Console.WriteLine(x.GetType().Name);//Int64
Console.ReadKey();

调用构造器并调用初始化器

using System;

namespace TestApp
{     
    class User
    {
        public int UserID;
        public string UserName;
    }
    class Program
    {   
        static void Main(string[] args)
        {
            //调用构造器并调用初始化器
            //User user = new User() { UserID = 1, UserName = "JunChow" };
            Console.WriteLine(new User() { UserID = 1, UserName = "JunChow" }.UserName);
            Console.ReadKey();
        }  
    }
}

语法糖

string name = "junchow";//string 类类型
int[] arr = { 1, 2, 3, 4};

var与匿名对象

//为匿名类型创建类型
var obj = new { Name = "username", Text = "Name" };
Console.WriteLine(obj.Name);//username
Console.WriteLine(obj.GetType().Name);//<>f__AnonymousType0`2

Console.ReadKey();

new操作符带来了依赖和紧耦合,可是依赖注入的设计模式可解耦和。

new作为关键字使用

子类对父类方法的隐藏

using System;

namespace TestApp
{     
    class User
    {
        public void Report()
        {
            Console.WriteLine("user");
        }
    }
    class Member:User
    {
        //子类对父类方法的隐藏
        new public void Report()
        {
            Console.WriteLine("member");
        }
    }
    class Program
    {   
        static void Main(string[] args)
        {
            User u = new User();
            u.Report();//user

            Member m = new Member();
            m.Report();//member

            Console.ReadKey();
        }  
    }
}

类型溢出检查操作符 check uncheck

uint x = uint.MaxValue;
Console.WriteLine(x);//4294967295

string bin = Convert.ToString(x, 2);
Console.WriteLine(bin);//11111111111111111111111111111111

try
{
    uint y = checked(x + 1);
}
catch (OverflowException ex)
{
    Console.WriteLine("overflow: "+ex.Message);
    //overflow: Arithmetic operation resulted in an overflow.
}

//上下文语句块
checked
{
    try
    {
        uint y = x + 1;
    }
    catch (OverflowException ex)
    {
        Console.WriteLine("overflow: " + ex.Message);
        //overflow: Arithmetic operation resulted in an overflow.
    }
}
                                                        
Console.ReadKey();

委托操作符 deligate

委托其实也就是匿名方法,现已被lambda表达式所替代。

using System;

namespace TestApp
{
    // 声明委托类型
    delegate void Output(int val);
    class Program
    {   
        void Start(int val)
        {
            Console.WriteLine(val);
        }
        void Stop(int val)
        {
            Console.WriteLine(val);
            Console.ReadKey();
        }
        static void Main(string[] args)
        {
            Program p = new Program();
            Output output;//声明委托变量

            Random rd = new Random();
            int val = rd.Next(999999);

            output = val < 100000 ? new Output(p.Start) : new Output(p.Stop);
            output(val);
        }  
    }
}

数据大小 sizeof

sizeof操作符获取结构体数据类型在内存中所占字节数

using System;

namespace TestApp
{                             
    struct Test
    {
        int id;
        long value;
    }
    class Program
    {         
        static void Main(string[] args)
        {
            //Console.WriteLine(sizeof(int));

            unsafe
            {
                int x = sizeof(Test);
                Console.WriteLine(x);//16
            }
            Console.ReadKey();
        }  
    }
}
unsafe

指针访问操作符 ->

指针操作需要放在不安全上下文环境中

using System;

namespace TestApp
{    
    struct Test
    {
        public int id;
        public long score;
    }
    class Program
    {         
        static void Main(string[] args)
        {

            unsafe
            {
                Test test;
                test.id = 1;
                test.score = 100;

                Test* p = &test;
                p->score = 200;

                Console.WriteLine(test.score);//200
            }
            Console.ReadKey();
        }  
    }
}

一元操作符

取地址操作符 &

正负非反

int intMin = int.MinValue;
//int intMax = int.MaxValue;
int intMax = ~intMin;

Console.WriteLine(intMin);//-2147483648
Console.WriteLine(Convert.ToString(intMin, 2).PadLeft(32,'0'));//10000000000000000000000000000000

Console.WriteLine(intMax);//2147483647
Console.WriteLine(Convert.ToString(intMax, 2).PadLeft(32,'0'));//01111111111111111111111111111111

Console.ReadKey();

求相反数 按位取反再加1


int intMin = int.MinValue;   
int val = -intMin;

Console.WriteLine(intMin);
Console.WriteLine(Convert.ToString(intMin, 2).PadLeft(32,'0'));

Console.WriteLine(val);
Console.WriteLine(Convert.ToString(val, 2).PadLeft(32, '0'));

Console.ReadKey();

取非操作符

using System;

namespace TestApp
{
    class User
    {
        public string UserName;
        public User(string username)
        {
            if (!string.IsNullOrEmpty(username))
            {
                this.UserName = username;
            }
            else
            {
                throw new ArgumentException("username is not null or empty");
            }
        }
    }
    class Program
    {         
        static void Main(string[] args)
        {
            User u = new User(null);
            Console.WriteLine(u.UserName);
            Console.ReadKey();
        }  
    }
}

前置自增自减

后置自增自减

强制类型转换

详见 类型转换

算术运算符

类型提升

var x = 3.0 * 4;
Console.WriteLine(x.GetType().FullName);//System.Double
Console.WriteLine(x);//12
Console.ReadKey();
var x = double.NegativeInfinity;
var y = double.PositiveInfinity;
var result = x / y;
Console.WriteLine(result.GetType().FullName);
Console.WriteLine(result); //NaN
Console.ReadKey();

左移右移

var x = 7;
var y = x<<1;                     
Console.WriteLine(Convert.ToString(x,2).PadLeft(32, '0')); 
Console.WriteLine(Convert.ToString(y,2).PadLeft(32, '0')); 
Console.ReadKey();
char c1 = 'a';
char c2 = 'A';
ushort u1 = (ushort)c1;
ushort u2 = (ushort)c2;
Console.WriteLine("{0} = {1} {2} = {3}", c1, u1, c2, u2);
Console.ReadKey();

类型检验操作符

using System;

namespace Test
{
    class User
    {
       public void Login()
        {
            Console.WriteLine("user login");
        }
    }
    class Member : User
    {

    }
    class Role
    {

    }
    class Program
    {
        static void Main(string[] args)
        {
            //User user = new User();
            //Member member = new Member();
            //var result = member is User;
            //Console.WriteLine(result.GetType().FullName);
            //Console.WriteLine(result);

            //object obj = new Role();
            //if(obj is Role)
            //{
            //    Role role = (Role)obj;
            //}

            object obj = new User();
            User user = obj as User;
            if(user != null)
            {
                 user.Login();
            }


            Console.ReadKey();
        }
    }
}

按位

Console.WriteLine(Convert.ToString(7, 2).PadLeft(32, '0'));
Console.WriteLine(Convert.ToString(8, 2).PadLeft(32, '0'));
Console.WriteLine(Convert.ToString(7&8, 2).PadLeft(32, '0'));

Console.ReadKey();

00000000000000000000000000000111
00000000000000000000000000001000
00000000000000000000000000000000

短路效应

int x = 8;
int y = 4;
int z = 5;
if(x>y && z++ > 5)
{
    Console.WriteLine("test");
}
Console.WriteLine(z);
Console.ReadKey();

可空类型

Nullable<int> x = null;
x = 100;
Console.WriteLine(x);
Console.WriteLine(x.HasValue);
Console.ReadKey();
int? x = 100;
Console.WriteLine(x);
Console.WriteLine(x.HasValue);
Console.ReadKey();

空值合并

int? x = 100;
int y = x ?? 0;
Console.WriteLine(y);          
Console.ReadKey();

条件操作符

int type = 1;
string str = string.Empty;
str =  (type > 1) ? "success" : "error";
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • 对于一个运算符函数来说,它或者是类的成员,或者至少是含有一个类型的对象。 对箭头运算符来说,不 有不能重载的运算符...
    HenryTien阅读 374评论 0 1
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,965评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 1、 你是什么样的人,就会吸引来什么样的人。物以类聚,人以群分。 2、外面的世界没有别人,只有你自己。周围所有的人...
    张允智阅读 2,041评论 5 51
  • 概要:分布式系统设计理念、CAP定理、BASE理论 一、分布式设计理念 目标:提升性能和吞吐量,尽量保证容错性 1...
    hedgehog1112阅读 325评论 0 0