今日学习计划
- 阅读《C#图解教程》
接口、转换(已完成)、泛型(未完成)章节内容。 - 跟随B站视频学习SQLServer
数据插入、修改和删除,条件查询(已完成)、模糊查询、分组查询、多表查询(未完成)。 -
进行充电体验(已完成)。
C#接口、转换
主要内容为《C#图解教程》中章节,不过多赘述,以下记录印象较为深刻内容。
1.使用IComparable接口的示例
Array类提供Sort方法可以对传入int数组进行升序排序,其实依赖于其实现了IComparable接口中唯一方法CompareTo。
public interface IComparable
{
int CompareTo(object obj);
}
.NET文档写道,在调用CompareTo方法时,应当返回以下几个值之一:
- 负数值,表示当前对象小于参数对象;
- 正数值,表示当前对象大于参数对象;
- 零,表示两个对象在比较时相等。
自定义MyClass类,实现IComparable接口,使其能作为Array.Sort方法参数被排序,代码示例如下:
class Program
{
static void Main(string[] args)
{
var myInt = new[] { 20, 4, 16, 9, 2 };
MyClass[] mcArr = new MyClass[5];
for (int i = 0; i < 5; i++)
{
mcArr[i] = new MyClass();
mcArr[i].TheValue = myInt[i];
}
PrintOut("Initial Order: ", mcArr);//打印排序前
Array.Sort(mcArr);
PrintOut("Sorted Order: ", mcArr);//打印排序后
}
static void PrintOut(string s, MyClass[] mc)
{
Console.Write(s);
foreach (var m in mc)
{
Console.Write("{0}\t",m.TheValue);
}
}
class MyClass : IComparable//实现IComparable接口
{
public int TheValue;//待排序的值
public int CompareTo(object obj)//实现CompareTo方法
{
MyClass myClass = (MyClass)obj;
if (this.TheValue > myClass.TheValue)//当前MyClass对象的TheValue值大于传入对象的值,返回正整数1
{
return 1;
}
if (this.TheValue < myClass.TheValue)//否则,返回负整数-1
{
return -1;
}
return 0;//返回0,表示两个对象的TheValue值相等
}
}
}

运行效果图
2.声明接口
- 接口声明不能包含以下成员:
- 数据成员
- 静态成员
- 按照惯例,接口名称必须从大写的I开始(比如IComparable)。
- 接口声明中函数成员不用实现,即没有代码块,用分号结尾。
- 接口成员是隐式public的,且不允许添加任何访问修饰符。
3.实现接口
- 在基类列表中包括接口名称,即:实现的类或接口 :接口。
- 接口中的所有成员都要提供具体实现。
-
如果类从基类继承并实现了接口,基类列表中的基类名称必须放在所有接口之前(只允许有一个基类)。
4.接口和as运算符
- 如果我们尝试将类对象引用强制转换为类未实现的接口禁用,操作会抛出一个异常,C#中可以通过使用as运算符来避免这个问题:
- 如果类实现了接口,表达式返回指向接口的引用。
- 如果类没有实现接口,表达式返回null而不是抛出异常。
ILiveBirth b = a as ILiveBirth;//与ILiveBirth b = (ILiveBirth)a一样
if(b != null)
Console.WriteLine("Baby is called: {0}",b.BabyCalled());
5.实现具有重复成员的接口
如果一个类实现了多个接口,并且其中一些接口有相同签名和返回类型的成员,那么类可以实现单个成员来满足所有包含重复成员的接口,示例代码如下:
interface IIfc1
{
void PrintOut(string s);
}
interface IIfc2
{
void PrintOut(string s);
}
class MyClass : IIfc1, IIfc2//实现两个接口
{
public void PrintOut(string s)//两个接口重复成员方法的单一实现
{
Console.WriteLine("Calling through: {0}", s);
}
}
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
mc.PrintOut("object");
}
}

运行效果图
除了单一实现之外,也可以显式接口成员实现,即使用限定接口名来声明。
class MyClass:IIfc1,IIfc2
{
void IIfc1.PrintOut(string s){...}//显示实现
void IIfc2.PrintOut(string s){...}
}
static void Main()
{
MyClass mc = new MyClass();
IIfc1 ifc1 = (IIfc1)mc;//获取IIfc1的引用
ifc1.PrintOut("Interface 1");//调用显式实现
IIfc2 ifc2 = (IIfc2)mc;
ifc2.PrintOut("Interface 2");
}
6.隐式转换
有些类型的转换不会丢失数据或精度,C#语言会自动做这些转换,叫做隐式转换。
-
从位数更少的源转换为位数更多的目标类型时,目标中多出来的位用0或1填充;当更小的无符号类型转换为更大的无符号类型时,目标类型多出来的最高位都以0填充,叫做零扩展。
无符号转换中的零扩展 -
对于有符号类型的转换,额外的高位用源表达式的符号位进行填充,叫做符号扩展。
有符号转换中的符号扩展
7.显式转换和强制转换
对于源类型的任意值在被转换成目标类型时会丢失值的情况,语言是不会提供这两种类型的自动转换的。此时必须使用显示转换,即强制转换表达式,将var1的值转换为sbyte类型构成如下:
//(目标类型) 源表达式
(sbyte) var1;
8.转换类型
- 除了标准转换,还可以自定义显式和隐式转换。
- 装箱,即将任何值类型转换为:object类型和System.ValueType类型。
-
拆箱,即将一个装箱的值转换为原始类型,即引用类型转换为值类型。
转换的类型
数字的转换
9.溢出检测上下文
代码片段是否被检查被称为溢出检测上下文,默认不检查。
- 如果指定一个表达式或代码片段为checked,CLR在转换产生溢出时抛出一个OverflowException异常。
- 如果代码没有checked,转换继续,不论是否产生溢出。
checked和unchecked运算符,使用方法:checked/unchecked (表达式/代码片段)。
剩余“引用转换”、“装箱/拆箱转换”、“用户自定义转换”、“is/as运算符”见《C#图解教程》内容更为详细。
SQLServer数据的插入、修改、删除
主要跟随B站UP主“屌丝学编程”的《SQLServer基础教程》学习,详情参见BV1XV411C7TP,以下记录个人印象较深的内容。
1.一次插入多条数据
--语法
insert into 表名(字段名1,字段名2,...)
select 值1,值2,... union
select 值1,值2,... union
select 值1,值2,... --最后一条数据处不需要添加union
--示例
insert into Department(DepartmentName,DepartmentRemark)
select '市场部','吹牛的部门' union
select '产品部','天马星空的部门' union
select '总经办','都是领导的部门'
字段数据类型为数字类型,在赋值的时候不需要添加单引号,而其它类型需要添加单引号。
2.删除数据drop、truncate、delete区别
- drop table:删除表对象,表数据、表结构、表对象都进行了删除。
- delete和truncate table:删除表数据,表对象及表结构依然存在。
delete与truncate table的区别如下:
delete: - 可以删除表所有数据,也可以根据条件删除数据。
- 如果有自动编号,删除后继续编号,例如delete删除表所有数据后,之前数据的自动编号是1,2,3,那么之后新增数据的编号从4开始。
truncate table: - 只能清空整个表数据,不能根据条件删除数据。
- 如果有自动编号,清空表数据后重新编号,例如truncate table清空表所有数据后,之前数据的自动编号是1,2,3,那么之后新增数据的编号仍然从1开始。
3.查询不重复的数据
--语法
select distinct 字段名 from 表名
--示例,查询公司员工所在城市(不需要重复数据)
select distinct PeopleAddress from People
4.查询数据排序
--语法,order by: 排序 asc: 正序 desc: 倒序
select * from 表名 order by 字段名 desc/asc
5.查询top数据
--查询top n的数据
select top n * from 表名 order by 字段名 desc
--查询top n%的数据
select top n percent * from 表名 order by 字段名 desc
6.查询生肖的员工记录
--查询生肖为鼠的员工数据,思路:简化生肖为12年一个轮回,根据余数确定生肖年份。
select * from People where year(PeopleBirth) % 12 = 4--year(PeopleBirth)计算年份
--查询所有员工信息,添加一列显示属相(鼠,牛,虎,兔,龙,蛇,马,羊,猴,鸡,狗,猪)
--方案一:
select PeopleName 姓名,PeopleSex 性别,PeopleSalary 工资,PeoplePhone 电话,PEOPLEBIRTH 生日,
case
when year(PeopleBirth) % 12 = 4 then '鼠'
when year(PeopleBirth) % 12 = 5 then '牛'
when year(PeopleBirth) % 12 = 6 then '虎'
when year(PeopleBirth) % 12 = 7 then '兔'
when year(PeopleBirth) % 12 = 8 then '龙'
when year(PeopleBirth) % 12 = 9 then '蛇'
when year(PeopleBirth) % 12 = 10 then '马'
when year(PeopleBirth) % 12 = 11 then '羊'
when year(PeopleBirth) % 12 = 0 then '猴'
when year(PeopleBirth) % 12 = 1 then '鸡'
when year(PeopleBirth) % 12 = 2 then '狗'
when year(PeopleBirth) % 12 = 3 then '猪'
ELSE ''
end 生肖
from People
--方案二:
select PeopleName 姓名,PeopleSex 性别,PeopleSalary 工资,PeoplePhone 电话,PEOPLEBIRTH 生日,
case year(PeopleBirth) % 12
when 4 then '鼠'
when 5 then '牛'
when 6 then '虎'
when 7 then '兔'
when 8 then '龙'
when 9 then '蛇'
when 10 then '马'
when 11 then '羊'
when 0 then '猴'
when 1 then '鸡'
when 2 then '狗'
when 3 then '猪'
ELSE ''
end 生肖
from People
充电体验
嘛,一次不太顺利的充电体验,一次完美的网约车乘客体验。(坐车两小时,充电1分钟)

TeldAPP

充电桩
学习资料链接
- 书籍:《C#图解教程》
- 视频:B站视频“SQL SERVER数据库_屌丝学编程”,BV1XV411C7TP。




