首页 .Net C#基本知识-关键字与数据类型

C#基本知识-关键字与数据类型

C#访问修饰符

访问修饰符的作用

访问修饰符是用于指定成员或类型的声明可访问性的关键字。

四种常见的访问修饰符

  • public(公共的)

  • protected(受保护的)

  • internal(内部的)

  • private(私有的)

访问修饰符的六种组合及其可访问性级别

  • public 访问不受限制

  • protected 访问限于包含类或派生自包含类的类型

  • internal 访问限于当前程序集

  • private 访问限于包含类

  • protected internal 访问限于当前程序集或派生自包含类的类型访问

  • private protected 访问限于包含类或当前程序集中包含类的派生类的类型访问

//包含类
public class BaseClass
{
    private protected int myValue = 0;
}

//当前程序集中包含类的派生类
public class DerivedClass1 : BaseClass
{
    void Access()
    {
        var baseObject = new BaseClass();
        myValue = 5;
    }
}

C#类和结构默认访问修饰符

Internal

C#适用于类和结构访问修饰符有哪些

public 或 internal

类成员和结构成员的默认访问修饰符为

private

结构成员(包括嵌套的类和结构)可以声明为

public、internal 或 private 注意:结构成员无法声明为 protected、protected internal 或 private protected,因为结构不支持继承。

类成员(包括嵌套的类和结构)可以声明为

public、protected internal、protected、internal、private protected 或 private

参考文章

  1. 访问修饰符(C# 参考)

readonly与const区别?

readonly关键字(运行时常量):字段可以在声明或构造函数中初始化,常作为运行时常量使用。

const关键字(编译时常量):字段只能在该字段的声明时初始化,常作为编译时常量使用过。

virtual作用?

详情阅读:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/virtual

virtual关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写(使用override关键字对虚方法重写)。 如下是虚方法声明和重写虚方法的示例:

   // 基类虚方法声明
   class BaseClass  
    {  
        public virtual void Method1()  
        {  
            Console.WriteLine("Base - Method1");  
        }  
  
        public virtual void Method2()  
        {  
            Console.WriteLine("Base - Method2");  
        }  
    }  
  
    class DerivedClass : BaseClass  
    {  
        // 重写基类中的虚方法
        public override void Method1()  
        {  
            Console.WriteLine("Derived - Method1");  
        }  
  
        public new void Method2()  
        {  
            Console.WriteLine("Derived - Method2");  
        }  
    }

override作用?

扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现需要 override 修饰符。

static作用?

详情阅读:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/static

使用 static 修饰符可声明属于类型本身而不是属于特定对象的静态成员。 static 修饰符可用于声明 static 类。 在类、接口和结构中,可以将 static 修饰符添加到字段、方法、属性、运算符、事件和构造函数。 static 修饰符不能用于索引器或终结器。

静态类与非静态类的区别?

  1. 静态类无法实例化(换句话说,无法使用 new 运算符创建类类型的变量。 由于不存在任何实例变量,因此可以使用类名本身访问静态类的成员)。

  2. 静态构造函数只调用一次,在程序所驻留的应用程序域的生存期内,静态类会保留在内存中(即使用Static修饰的类,应用一旦启用静态类就会保留在内存中)。

  3. 静态类只包含静态成员

  4. 不能包含实例构造函数

  5. 静态类会进行密封,因此不能继承。 它们不能继承自任何类(除了 Object)。 静态类不能包含实例构造函数。 但是,它们可以包含静态构造函数。

静态成员和非静态成员的区别?

成员主要指的是:字段、方法、属性、运算符、事件和构造函数等。

  1. 静态成员用static修饰符,非静态成员不需要。

  2. 静态成员属于类所有,非静态成员属于类的实例化对象所有。

  3. 静态方法里不能使用非静态成员,非静态方法可以使用静态成员。

  4. 每创建一个类的实例,都会在内存中为非静态成员新分配一块新的存储。

  5. 静态成员无论类创建多少个实例,在内存中只占同一块区域。

静态方法的使用场合

  1. 静态方法最适合工具类中方法的定义。

  2. 静态变量适合全局变量的定义。

静态方法和非静态方法区别(优/缺点)?

优点

  1. 属于类级别的,不需要创建对象就可以直接使用。

  2. 全局唯一,内存中唯一,静态变量可以唯一标识某些状态。

  3. 在类加载时候初始化,常驻在内存中,调用快捷方便。

缺点

  1. 静态方法不能调用非静态的方法和变量。(非静态方法可以任意的调用静态方法/变量

  2. 不可以使用 this 引用 static 方法或属性访问器。

using关键字的作用

  1. using指令为命名空间创建别名,或导入在其他命名空间中定义的类型

  2. using 语句定义一个范围,在此范围的末尾将释放对象资源,实现了IDisposiable的类在using中创建,using结束后会自定调用该对象的Dispose方法,释放资源。

不能将 in、ref 和 out 关键字用于以下几种方法:

  • 异步方法,通过使用 async 修饰符定义。

  • 迭代器方法,包括 yield return yield break 语句。

  • 扩展方法的第一个参数不能有 in 修饰符,除非该参数是结构。

  • 扩展方法的第一个参数,其中该参数是泛型类型(即使该类型被约束为结构。)

C#中参数传递 ref与out 的区别?

ref 指定此参数由引用传递,指定的参数在函数调用时必须先初始化(有进有出)。

out 指定此参数由引用传递,指定的参数在进入函数时会清空参数值,因此该参数必须在调用函数内部进行初始化赋值操作(无进有出)。

as和is的区别

  1. is 只是做类型兼容判断,并不执行真正的类型转换。返回true或false,不会返回null,对象为null也会返回false。

  2. as运算符将表达式结果显式转换为给定的引用类型或可以为null值的类型。 如果无法进行转换,则as运算符返回 null。

总结:as模式的效率要比is模式的高,因为借助is进行类型转换的化,需要执行两次类型兼容检查。而as只需要做一次类型兼容,一次null检查,null检查要比类型兼容检查快。

null是什么类型?

null 关键字是表示不引用任何对象的空引用的文字值。 null是引用类型变量的默认值。 普通值类型不能为 null,可为空的值类型除外。

new关键字的作用?

  1. 运算符:创建类型的新实例

  2. 修饰符:可以显式隐藏从基类继承的成员。

  3. 泛型约束:泛型约束定义,约束可使用的泛型类型。

contiune、break、return的区别?

return:

结束整个方法,return关键字并不是专门用于跳出循环的,return的功能是结束一个方法。 一旦在循环体内执行到一个return语句,return语句将会结束该方法,循环自然也随之结束。与continue和break不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。

contiune:

结束本次循环,然后持续进行下一次循环。

break:

break用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到break,系统将完全结束循环,开始执行循环之后的代码。


在C#中,变量主要分为以下几种类型:

  • 值类型(Value Types)

  • 引用类型(Reference Types)

  • 指针类型(Pointer Types)

值类型(Value Types)主要包括哪些?

顺口溜:整浮布字结枚(实际数据存储栈中,操作系统负责管理分配释放)

  • 整型数值类型

  • 浮点型数值类型

  • 布尔类型(bool)

  • 字符类型(char)

  • 结构类型(struct type)

  • 枚举类型(enum type)

引用类型(Pointer Types)主要包括哪些?

顺口溜:对字类接委动(实际数据存储在堆中,GC负责管理分配释放)

  • 对象类型(object)

  • 字符串类型(string)

  • 类(class)

  • 接口(interface)

  • 委托类型(delegate)

  • 动态类型(dynamic)

C#值类型和引用类型的区别?

1、速度上的区别
值类型存取速度快,引用类型存取速度慢。

2、用途上的区别
值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用。

3、来源上的区别
值类型继承自System.ValueType,引用类型继承自System.Object

4、位置上的区别
值类型的数据存储在内存的栈中,引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

5、类型上的区别
值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。

6、保存位置上的区别
值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中,而实际数据则保存在堆中。

C#装箱和拆箱

什么是装箱和拆箱?
装箱:将值类型转化为引用类型的过程。
拆箱:将引用类型转化为值类型的过程。

装箱和拆箱的作用
C#中值类型和引用类型的最终基类都是Object类型(它本身是一个引用类型)。
也就是说,值类型也可以当做引用类型来处理。而这种机制的底层处理就是通过装箱和拆箱的方式来进行,利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来 。
但是装箱和拆箱的过程会有性能的消耗,所以一般情况下我们建议使用泛型。

装箱和拆箱转化的性能问题
相对于简单的赋值而言,装箱和取消装箱过程需要进行大量的计算。 对值类型进行装箱时,必须分配并构造一个新对象。 取消装箱所需的强制转换也需要进行大量的计算,只是程度较轻。

C#如何判断变量是什么类型?
有如下两种方式:
"追逐时光者".GetType()获取当前实例准确的运行时类型。
is关键字判断对象变量是否是指定的类型。

动态类型与 object 类型的区别
object 类型是.NET 里面 System.Object 的别名,在 C#中所有的类型(预定义、用户定
义、引用类型、值类型)都直接或者间接的继承自 Object。



特别声明:本站部分内容收集于互联网是出于更直观传递信息的目的。该内容版权归原作者所有,并不代表本站赞同其观点和对其真实性负责。如该内容涉及任何第三方合法权利,请及时与824310991@qq.com联系,我们会及时反馈并处理完毕。