【游戏开发笔记】编程篇_C#面向对象{上}

@

1.变量和表达式

1.1注释

  • 单行注释://
  • 多行注释:/**/
  • 文档注释:///
    VS编译后,会产生一个文本文件,该文件可创建文档

1.2C#控制台程序基本结构

using System;
namespace ConsoleApplication1
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("The first App in Begining C# Program!");
			Console.Readkey();
		}
	}
}

折叠预处理

#region 
……
……
#endregion

(折叠中间部分)

1.3变量(从存储长度来看)

  • 转义字符:为了将字面值赋给变量不出错
    eg:
    string myString = "\"string\" is";

  • 整数
    sbyte [-128, 127] 8位
    byte [0, 255] 8位
    short [-32 768, 32767] 16位
    ushort [0, 65535] 16位
    int [-2 147 483 648, 2 147 483 647] 32位
    uint [0, 4 294 967 296] 32位
    long [9 223 372 036 854 775 808, 9 223 372 036 854 775 807] 64位
    ulong [0, 18 446 744 073 709 551 615] 64位

  • 浮点
    前两种存储类型:+/- m x 2^e
    后一种存储方式:+/- m x 10^e
    类型 m-min m-max e-min e-max
    float 0 2^24 -149 104
    double 0 2^53 -1075 970
    decimal 0 2^96 -28 0

  • 文本和布尔
    char [0, 65 535]
    bool ture/false
    string 没有上限

1.4变量的命名

1、变量名的第一个字母必须是字母、下划线或@
2、其后可以是字母、下划线或数字
3(注意)变量名不能是关键字

1.5字面值

类型							后缀
int, uint, long, ulong			无
uint、ulong						u或U
long、ulong						l或L
ulong					(u、l 位置关系和大小写不影响)Ul,Lu……均可
float						f或F
double						无、d或D
decimal						m或M

@置于字符串最前端,无需转义,即可正确存储和表达字面值

1.6运算符

  • 比较运算符
    ==、!=、<、>、<=、>=

  • 条件运算符
    &&、| |

  • 赋值运算符
    =、+=、-=、*=、/=、%=、&=、|=、^=

  • 其他
    一元:++、--,+(正)、-(负)
    三元:逻辑表达式?a:b
    逻辑表达式成立,三元表达式值为a,否则为b
    二元:+、-、*、/……

  • 优先级
    (优先级记忆不用担心,因为写代码时一般会使用括号指定优先级,增加可读性)

1、前缀:++,--,一 元:+,-
2、,/,%
3、+,-
4、>>、<<
5、>、<、>=、<=
6、==, !=
7、&
8、^
9、|
10、&&
11、| |
12、=,+=,-=,
=,/=、<<=、>>=、&=、|=、^=
后缀:++,--

2流程控制

该部分同c

2.1分支

三元运算符

<test>? <resultIfTrue> : <resultIfFalse>

if语句

if (<test>)
	<code executed if <test> is true>;

if (<test>)
	<code executed if <test> is true>;
else
	<code executed if <test> is false>;

[效果同三元运算符]

if (varl == 1)
{
	// Do something.
}
else if (varl == 2)
{
	// Do something else.
}
else
{
	// Do something else.
}

switch语句

switch (<testVar>)
{
	case <comparisonVal1>:
	<code to execute if <testVar> == <comparisonVal1> >
	break;
	case <comparisonVal2>:
	<code to execute if <testVar> == <comparisonVal2> >
	break;	
	……
	case <comparisonValN>:
	<code to execute if <testVar> == <comparisonValN> >
	break;
	default:
	<code to execute if <testVar> != <comparisonVals> >
	break;
}

2.2循环

do循环

do
{
	<code to be looped>
}while (<Text>)

while循环

while (<Text>)
{
	<code to be looped>
}

for循环

for (<initialization>; <condition>; <operation>)
{
	<code to loop>
}

无限循环

while (ture)
{}

for (; ;)
{}

……

3变量知识拓展

3.1类型转换

  • 隐式转换
  • 显式转换
(<destinationType>) <sourceVar>

3.2枚举

  • 定义
enum <typeName>:<underlyingType>
{
	<value1> = <actualVal1>
	<value2> = <actualVar2>
	……
	<valueN> = <actualVarN>
}

(数据默认为int类型,每个值根据顺序定义【从0开始】)
声明新类型的变量

<typeName> <varName>
  • 赋值:
<varName> = <typeName>.<value>;

3.3结构(体)

  • 定义
struct <typeName>
{
	<memberDeclarations>
}
  • 结构的数据成员
<memberDeclarations>
  • 部分包含变量的声明:
<accessibility> <type> <name>

定义结构类型的变量类似枚举
可以通过句点字符访问这个组合变量中的数据成员

3.4数组

数组的索引是从0算起,如果要查找数组中第三个元素,语法为:myArray[2]

  • 定义:
<baseType> [ ] <name>

(必须在访问之前初始化)
举例

int [] myIntArray = {1, 2, 3};

或,int [] myIntArray = new int[arraySize];
arraySize可以是常数,也可以是变量
或,int [] myIntArray = new int[10] {2, 5, 5};
foreach循环

遍历数组中每一个元素

foreach (<baseType> <name> in <array>)
{
	// can use <name> for each element
}

多维数组
[, ] ;
与一位数组类似,只是使用的时候需要更多的逗号和更多的大括号,数据在内存中顺序存储
eg:double [, ] hillHight = new double[3, 4] {{2, 3 , 4, 5}, {2, 33, 55.7, 5}, {2, 5}};
数组的数组
声明:int[ ] [ ] jaggedIntArray;

  • 初始化:
jaggedIntArray = new int [2] [ ];
jaggedIntArray [0] = new int [3];
jaggedIntArray [0] = new int [2];
//或是下面这样
jaggedIntArray = new int [3] [ ]{
	new int [2] {2, 4}, new int [3] {2, 3,  4},
	new int [1] {5} };
  • 又或声明与初始化放一起
int [ ] [ ] jaggedIntArray = new int [3] [] {
	new int [2] {2, 4}, new int [3] {2, 3,  4},
	new int [1] {5} };
  • foreach实现遍历
foreach (int [ ] sonArray in fatherArray)
{
	foreach (int sprit in sonArray)
	{
		// work;
	}
}

3.5字符串的处理

  • 思路
  • 转为字符数组,(一般)使用封装好的方法操作即可
    1、字符串转字符数组:<stringName>. ToCharArray( ) 【其后方法使用方式一致】,有返回值
    2、获取字符串中字符数:Length( ),有返回值
    3、转为大,小写:ToUpper( ), ToLower( ),有返回值
    4、删除指定字符:Trim(需要的字符),有返回值,默认删除字符串前后空格
    5、删除字符串前后空格:TrimStart( ), TrimEnd( ), 有返回值
    6、在字符串左边或右边添加指定字符至指定长度:PadLeft(<length>,<char> ), PadRight(<length> , <char>), 有返回值,默认添加空格

4函数

static <returnType> <FunctionName>( <type> <typeName>)
{
	// do something.
	return <typeVar>
}

如果是void类型,则之间return; 或省略不写

4.1返回值

如果方法有返回值,在方法体内,所有情况下,都必须有返回内容,否则会报错 “并不是所有的处理路径都用返回值”

针对一行代码的方法,可以使用 表达式体方法(expression-bodied method)处理
如:

static double Multiply (double myVal1, double myVal2)
{
	return myVal1 * myVal2;
}

可改写为:

static double Multiply (double myVal1, double myVal2) => myVal1 * myVal2;

4.2参数

  • 参数匹配
    参数类型、个数。顺序 在定义与使用时保持一致

  • 参数数组
    只能指定一个特殊参数

    可以传递同类型的多个参数:

static <returnType> <FunctionName> (params <type>[ ] <name>)

{

	……

	return <returnValue>

}
  • 引用参数和值参数
    把变量作为一个参数,调用方法时并不影响主函数中变量的值。

    (实质是重新开辟了一块空间,传参时将变量给新空间复制了一份,在方法执行完毕后,复制的变量就会和方法一起被清理掉,而原来的参数并没有参与方法中的任何操作)

    改变原变量的方法:

    1、使用返回值

    缺点:不直观、只有一个返回值

    2、使用ref 限定

static void ShowDouble ( ref int val)

{

	val *= 2;

	WriteLine($ "val double = {val}");

}

调用(必须加 ref):

int myNumber = 5;

ShowDouble( ref myNumber);

ref的限制:

a、值参数必须是“非常量”变量

b、必须使用初始化过的变量

3、使用全局变量——可读性差

  • 输出参数
    out
    使用方法及作用同ref

    区别:
    1、未赋值的变量可以做out的参数,但不能做ref的参数
    2、函数使用out参数时,必须将其看作未赋值的

5.调试和错误处理

5.1 VS中调试

  • 非中断模式下调试
    1.输出调试信息
Debug.WriteLine( )	//仅在调试模式下运行
Trace.WriteLine( )	//还可用于发布程序

2.跟踪点

  • 中断模式下调试
    1.断点进入
    Debug.Assert( )
    Trace.Assert( )

    第一个参数:布尔值,为false时触发语句
    第二个参数:字符串,将信息弹到对话框
    第三个参数:字符串,将信息弹到Output窗口

Debug.Assert ( myVar < 10, " my Var is 10 or qreater", "Assertion occurred in Main( ).")

2.语句进入

3.监视变量内容

4.单步执行

5.Immediate 和 Command 窗口
调整变量值,测试表达式
6.Call Stack 窗口
描述程序如何执行到当前位置

5.2 错误处理

  • try……catch……finally
try
{
	……
}

catch ( <exceptionType> e) when (filterIsTure)
{
	<await methodName( e); >
	……
}

finally
{
	<await method name>
	……
}

正常执行顺序:就像字面意思,先尝试执行 “try” 中的代码,如果有错误,跳到 “catch” 抓住异常,执行相应操作,最后“finally”。

catch的补充1:也可以将错误 “catch”后抛出:

catch(Exception)
{
	throw;
}

代码可以嵌套,因此如果外层代码仍没有处理抛出的异常,编译器就会迫使程序暂停(不能正常编译)

catch的补充2:如上述代码,catch后的括号里需要跟异常的类名,如果不知道异常的类名,可以选择跟异常之父——“Exception”。只有catch了正确的异常类——即程序异常的类名与catch后括号的类名一致时,才会执行catch中的代码,同理,可以有多个catch并列,但catch(Exception)只能位于最后。

eg:

try
{
	int[4] myArray = {1, 2, 3, 4};
	int myElem = myArray[ 4];
}

catch (Exception ex)
{
	Debug.WriteLine( ex.Message);
}
  • 列出和配置异常

6.面向对象编程

6.1 面向对象


  • 类:类是功能的封装,例:衣服
    对象:对象是类中的一个实例,例:第三行第二列的那件衣服

    C#中可以创建类,类中有成员。

    static问题:
    静态的即全局的,静态的类就可以通过点句运算符直接访问,参考Console()进行理解。

    静态构造函数调用时机:
    创建含静态函数的类实例
    访问含静态构造函数的类的静态成员
    1.构造函数
    构造函数——数据成员初始化
    本质:方法
    特点:没有返回值,与类同名

    例——用new调用默认构造函数,实例化一个对象:

CupOfCoffee myCup = new CupOfCoffee();

与可以是非默认构造函数:

CupOfCoffee myCup = new CupOfCoffee(" Blue Mountain");

构造函可public也可private,因此可以private默认构造函数,强制类的用户使用非默认构造函数
2.构析函数
归还内存

~<ClassName>()
{}  //当析构语块结束时,析构函数执行

也可以使用CG

CG.Collect( );	
//这个看CG的心情,CG觉得时机不成熟,即使有该语句也不会进行清理

3.方法
解决问题
4.字段
存储数据——变量
5.属性
保护字段读写

  • UML
    UML即Unified Modeling Language

是一种建模语言
类的表示:
第一行:类名
第二行:成员- 成员名: 成员类型
第三行:方法名( 标识符 参数名: 参数类型):方法类型
标识符:out 和 inout 分别对应 out 和 ref,in 不使用以上两种关键字(默认情况),return 表返回值
(注:二、三行“+、-”号表示public和private,下划线表private)

类似于伪代码,不受编程语言是语法限制,来表述问题解决思路。

6.2 OOP技术

  • 接口
    把公共实例(非静态)方法和属性组合起来,以封装特定功能的一个集合

    可理解为将多个有相似特性的类组合在一起的大类。
    (区别是:类只能继承一个,接口可以继承多个)

    可删除对象:使用using关键字后,代码块执行完毕,就会调用Dispose()方法,删除代码块

using (<ClassName > <VariableName> = new <ClassName>)
{
	……
}
  • 继承
    任何类都可以从另一个类继承
    基类——父类,派生类——子类
    注:C#的对象仅能直接派生一个基类

    可访问性:派生类不能访问基类的私有成员,可访问共有成员,外部代码同。
    第三种可访问性:protected。家族类可访问,外部代码不能。

    继承行为:基类成员可以是虚拟的,成员可以由继承它的类重写。派生类可以提供成员的另一种实现方法,这种实现代码不会删除原来的代码,但外部代码不能访问它们。如果没有提供其他实现方式,通过派生类使用成员的外部代码就自动访问基类中成员的实现代码。
    (虚拟成员不能是私有变量)

    抽象类:不能实例化,使用时必须继承它,并在派生类中重写。可封装功能

    类可密封,密封的类不能做基类。

    C#中,所有对象有一个共同的基类Object

  • 多态
    条件:有家族关系、有相同的类
    使用方法:调用类的方法需要一个过渡变量

//Cow是Animal的派生类,Cow继承Animal的EatFood方法
//且有一个基类没有的Moo()方法
Cow myCow = new Cow();
Animal myAnimal = myCow;
myAnimal.EatFood;
Cow myNewCow = (cow) myAniaml;
myNewCow.Moo();

使用环境:作用在同一个类的不同对象上执行任务

接口的多态性:条件——有方法、有共同接口
优势:不用依赖于一个公共的基类

唯一的区别:必须提供方法的实现代码

  • 对象之间的关系
    1.包含关系
    类似于继承
    *2.集合关系
    存储多个同类型的变量,类似于数组(变量即对象,万物皆可对象)

转载请注明出处

posted @ 2021-12-31 10:33  码农要战斗  阅读(84)  评论(0编辑  收藏  举报