- C# 基础教程
- C# - 首页
- C# - 概述
- C# - 环境
- C# - 程序结构
- C# - 基本语法
- C# - 数据类型
- C# - 类型转换
- C# - 变量
- C# - 常量
- C# - 运算符
- C# - 决策制定
- C# - 循环
- C# - 封装
- C# - 方法
- C# - 可空类型
- C# - 数组
- C# - 字符串
- C# - 结构体
- C# - 枚举
- C# - 类
- C# - 继承
- C# - 多态
- C# - 运算符重载
- C# - 接口
- C# - 命名空间
- C# - 预处理器指令
- C# - 正则表达式
- C# - 异常处理
- C# - 文件 I/O
C# - 面试题
尊敬的读者,这些C# 面试题专为帮助您了解在C#主题面试中可能遇到的问题类型而设计。根据我的经验,优秀的考官在面试期间很少会计划好要问哪些具体问题,通常问题会从该主题的一些基本概念开始,然后根据进一步的讨论和您的回答继续下去。
C# 是一种现代的、通用的、面向对象的编程语言,由微软开发。C# 是为公共语言运行时 (CLI) 设计的,它由可执行代码和运行时环境组成,允许在不同的计算机平台和架构上使用各种高级语言。
锯齿数组是数组的数组。
您可以这样初始化锯齿数组:
int[][] scores = new int[2][]{new int[]{92,93,94},new int[]{85,66,87,88}};
其中,scores 是一个包含两个整数数组的数组 - scores[0] 是一个包含 3 个整数的数组,scores[1] 是一个包含 4 个整数的数组。
可以通过三种方式向方法传递参数:
值参数 - 此方法将参数的实际值复制到函数的形式参数中。在这种情况下,对函数内部参数所做的更改不会影响参数。
引用参数 - 此方法将参数的内存位置的引用复制到形式参数中。这意味着对参数所做的更改会影响参数。
输出参数 - 此方法有助于返回多个值。
是的!使用输出参数。return 语句只能用于从函数返回一个值。但是,使用输出参数,您可以从函数返回两个值。
输出参数类似于引用参数,只是它们将数据从方法传出而不是传入。引用参数将参数的内存位置的引用复制到形式参数中。这意味着对参数所做的更改会影响参数。
命名空间旨在提供一种方法来使一组名称与另一组名称分开。在一个命名空间中声明的类名不会与在另一个命名空间中声明的相同类名冲突。
using 关键字用于在程序中包含命名空间。程序通常有多个 using 语句。
值类型变量可以直接赋值。它们派生自 System.ValueType 类。
值类型直接包含数据。一些示例包括 int、char 和 float,它们分别存储数字、字母和浮点数。当您声明 int 类型时,系统会分配内存来存储该值。
引用类型不包含存储在变量中的实际数据,而是包含对变量的引用。
换句话说,它们引用内存位置。使用多个变量,引用类型可以引用内存位置。如果一个变量更改了内存位置中的数据,则另一个变量会自动反映此值的变化。内置引用类型的示例包括:object、dynamic 和 string。
在 C# 通用类型系统 (CTS) 中,对象类型是所有数据类型的最终基类。Object 是 System.Object 类的别名。对象类型可以赋值任何其他类型的的值,值类型,引用类型,预定义或用户定义的类型。但是,在赋值之前,需要进行类型转换。
将值类型转换为对象类型时,称为装箱。
将对象类型转换为值类型时,称为拆箱。
您可以在动态数据类型变量中存储任何类型的 value 。这些类型的变量的类型检查在运行时进行。
声明动态类型的语法为:
dynamic <variable_name> = value;
例如:
dynamic d = 20;
动态类型类似于对象类型,不同之处在于对象类型变量的类型检查在编译时进行,而动态类型变量的类型检查在运行时进行。
指针类型变量存储另一种类型的内存地址。C# 中的指针具有与 C 或 C++ 中的指针相同的功能。
声明指针类型的语法为:
type* identifier;
例如
char* cptr; int* iptr;
is 运算符确定对象是否为某种类型。
If( Ford is Car) // 检查 Ford 是否是 Car 类的对象。
as 运算符进行强制转换,如果强制转换失败,则不会引发异常。
Object obj = new StringReader("Hello"); StringReader r = obj as StringReader;
封装被定义为“将一个或多个项目封装在物理或逻辑包中的过程”。在面向对象编程方法中,封装防止访问实现细节。
使用访问修饰符实现封装。
访问修饰符定义类成员的范围和可见性。
公共访问修饰符允许类将其成员变量和成员函数公开给其他函数和对象。任何公共成员都可以从类外部访问。
私有访问修饰符允许类将其成员变量和成员函数隐藏在其他函数和对象之外。只有相同类的函数才能访问其私有成员。即使是类的实例也不能访问其私有成员。
受保护的访问修饰符允许子类访问其基类的成员变量和成员函数。这样它有助于实现继承。
内部访问修饰符允许类将其成员变量和成员函数公开给当前程序集中的其他函数和对象。换句话说,任何具有内部访问修饰符的成员都可以从定义该成员的应用程序中定义的任何类或方法访问。
受保护内部访问修饰符允许类将其成员变量和成员函数隐藏在其他类对象和函数之外,除了相同应用程序中的子类之外。这在实现继承时也会用到。
C# 提供了一种特殊的数据类型,即可空类型,您可以为其赋值正常范围的值以及 null 值。
例如,您可以将 -2,147,483,648 到 2,147,483,647 之间的任何值或 null 存储在 Nullable<Int32> 变量中。类似地,您可以在 Nullable<bool> 变量中赋值 true、false 或 null。
空合并运算符与可空值类型和引用类型一起使用。它用于将操作数转换为另一个可空(或不可空)值类型操作数的类型,其中允许隐式转换。
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则它返回第一个操作数的值。
通过使用 params 关键字,可以指定一个方法参数,该参数接受可变数量的参数,甚至不接受任何参数。
不可以!在方法声明中,params 关键字之后不允许使用其他参数。方法声明中只允许使用一个 params 关键字。
Array 类是 C# 中所有数组的基类。它在 System 命名空间中定义。Array 类提供各种属性和方法来处理数组。
使用 Array.Sort(array) 函数。它使用数组的每个元素的 IComparable 实现来对整个一维数组中的元素进行排序。
首先使用 Array.Sort(array) 对数组进行排序,然后使用 Array.Reverse(array) 方法对其进行反转。
在 C# 中,结构体是一种值类型数据类型。它可以帮助您使单个变量保存各种数据类型的相关数据。struct 关键字用于创建结构体。
结构体用于表示记录。要定义结构体,必须使用 `struct` 语句。`struct` 语句定义了一种新的数据类型,它包含程序的多个成员。
类和结构体有以下基本区别:
类是引用类型,而结构体是值类型。
结构体不支持继承。
结构体不能有默认构造函数。
枚举是一组命名的整数常量。枚举类型使用 `enum` 关键字声明。
C# 枚举是值数据类型。换句话说,枚举包含其自身的值,不能继承也不能传递继承。
类类型的默认访问修饰符是 `internal`。
成员的默认访问权限是 `private`。
继承是面向对象编程中最重要的概念之一。继承允许我们根据另一个类来定义一个类,这使得创建和维护应用程序更加容易。这也提供了重用代码功能的机会,并加快了实现时间。
创建类时,程序员可以指定新类应该继承现有类的成员,而不是编写全新的数据成员和成员函数。这个现有类称为基类,新类称为派生类。
继承的概念实现了 IS-A 关系。例如,哺乳动物是动物,狗是哺乳动物,因此狗也是动物,依此类推。
不支持!C# 不支持多重继承。
一个类可以从多个类或接口派生,这意味着它可以继承多个基类或接口的数据和函数。C# 中用于创建派生类的语法如下:
<acess-specifier> class <base_class> { ... } class <derived_class> : <base_class> { ... }
多态性这个词意味着具有多种形式。在面向对象编程范式中,多态性通常表示为“一个接口,多个函数”。
多态性可以是静态的或动态的。在静态多态性中,对函数的响应是在编译时确定的。在动态多态性中,它是在运行时确定的。
C# 提供两种实现静态多态性的技术。它们是:
函数重载
运算符重载
在编译时将函数与对象链接的机制称为早期绑定。它也称为静态绑定。
您可以在同一作用域中为同一个函数名有多个定义。函数的定义必须通过参数列表中参数的类型和/或数量来区分。您不能重载仅返回类型不同的函数声明。
动态多态性由抽象类和虚函数实现。
当一个类被声明为密封类时,它不能被继承。
不可以!因为它不能创建,因为抽象类不能声明为密封类。
当您在类中定义一个要在继承类中实现的函数时,可以使用虚函数。虚函数可以在不同的继承类中以不同的方式实现,对这些函数的调用将在运行时决定。
您可以重新定义或重载 C# 中提供的大多数内置运算符。因此,程序员也可以将运算符与用户定义的类型一起使用。
重载的运算符是具有特殊名称的函数,关键字 `operator` 后跟被定义的运算符的符号。与任何其他函数类似,重载的运算符具有返回类型和参数列表。
接口定义为所有继承该接口的类都应遵循的语法约定。接口定义了语法约定的“什么”部分,派生类定义了语法约定的“如何”部分。
接口定义属性、方法和事件,这些是接口的成员。接口只包含成员的声明。派生类有责任定义成员。这通常有助于提供派生类将遵循的标准结构。
预处理器指令指示编译器在实际编译开始之前预处理信息。
所有预处理器指令都以 `#` 开头,并且在一行上预处理器指令之前只能出现空格字符。预处理器指令不是语句,因此它们不以分号 (;) 结尾。
您可以使用 `#if` 指令创建条件指令。条件指令用于测试符号或符号以检查它们是否计算结果为真。如果它们确实计算结果为真,则编译器将计算 `#if` 和下一个指令之间的所有代码。
C# 异常由类表示。C# 中的异常类主要直接或间接地从 `System.Exception` 类派生。一些从 `System.Exception` 类派生的异常类是 `System.ApplicationException` 类和 `System.SystemException` 类。
`System.ApplicationException` 类支持应用程序程序生成的异常。因此,程序员定义的异常应该从此类派生。
`System.SystemException` 类是所有预定义系统异常的基类。
下一步是什么?
接下来您可以回顾一下您之前完成的与该科目相关的作业,并确保您能够自信地谈论它们。如果您是应届毕业生,面试官不会期望您回答非常复杂的问题,而是您必须使您的基础概念非常扎实。
其次,如果您无法回答一些问题,这并不重要,重要的是您回答了什么问题,您必须充满信心地回答。所以在面试时要充满信心。我们在 tutorialspoint 祝您面试顺利,并祝您未来的事业一切顺利。干杯 :-)