操作符概览
- 操作符(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";