C#基础2024.07.02

目录

1.变量的作用域有哪些?

2.成员变量和静态变量的区别?

成员变量(实例变量)

静态变量(类变量)

3.利用递归,写个文件目录遍历,打印出文件名、扩展名、文件大小

4.简述访问修饰符有几种,各有什么不同?

(1)public

(2)private

(3)protected

(5)internal

(6)protected internal

5.重点比较public、protected、private的区别


1.变量的作用域有哪些?

(1)局部变量:方法体内变量、if 判断变量、for 循环中变量

void xx()
{
    int a = 10; //局部变量,方法体内,作用域
    a = 20;
}
for(int i=0; i<10; i++)
{
    i++; //局部变量,for 循环体内有效
}

(2)块级作用域:只在块内有效

{
    int x = 0; //块的变量,作用域,块内有效
    x = 10;
}

(3)方法参数作用域:只在方法体内生效

public int a(int i)  //i只在该函数方法体内生效
{
    i++;
    return i;
}

(4)全局变量:在整个对象的方法中都可以调用

class Rectangle //类名
{
    double length; //全局变量,成员变量
    double height; //全局变量,成员变量,可在该类中的任何一个方法中调用
}

(5)静态变量作用域:静态变量属于类级别,当类加载时就会被创建。无论创建了多少个类的实例,静态变量只有一个副本,本且这个副本对所有实例都是共享的。

普通成员变量:

internal class StaticVar
{
    //1.定义普通变量
    public int num; //成员变量

    //2.变量值改变
    public void count()
    {
        num++;
    }

    //3.获取最终的变量值
    public int get() { return num; }

    public static void Main()
    {
        StaticVar sv = new StaticVar();
        sv.count();
        sv.count();
        sv.count();
        Console.WriteLine(sv.get()); //输出结果为3

        StaticVar sv2 = new StaticVar();
        sv2.count();
        sv2.count();
        Console.WriteLine(sv2.get());  //输出结果为2
    }
}

静态成员变量:

internal class StaticVar
{
    //1.定义静态变量
    static public int num; //成员变量

    //2.变量值改变
    public void count()
    {
        num++;
    }

    //3.获取最终的变量值
    public int get() { return num; }

    public static void Main()
    {
        StaticVar sv = new StaticVar();
        sv.count();
        sv.count();
        sv.count();
        Console.WriteLine(sv.get()); //输出结果为3

        StaticVar sv2 = new StaticVar(); 
        sv2.count();
        sv2.count();
        Console.WriteLine(sv2.get()); 输出结果为5
    }
}

总结:

由上述两段代码我们可以看出当我们定义一个普通变量时,每创建一个对象就相当于创建了一个新的副本,两个对象中num的值互不干扰;但当我们定义一个静态变量时,创建的所有对象共享变量num。

2.成员变量和静态变量的区别?

(可参考第一题中(5)的代码进行比较)

成员变量(实例变量)

  • 所属范围:成员变量属于类的每个实例,即每次创建一个新的对象时,都会为这个对象分配一套新的成员变量。
  • 存储位置:成员变量存储在堆内存中,具体位于每个对象的实例数据部分。
  • 生命周期:成员变量的生命周期与创建它们的对象绑定,当对象被创建时它们存在,当对象被垃圾回收时它们消失。
  • 访问:成员变量通过特定对象的引用进行访问,通常使用点运算符(.)来访问,如 myObject.myMemberVariable
  • 初始化:成员变量可以在构造函数中初始化,或者直接在声明时初始化。

静态变量(类变量)

  • 所属范围:静态变量属于类本身,而不是类的实例。这意味着无论创建多少个类的实例,静态变量都只有一份拷贝。
  • 存储位置:静态变量存储在方法区(在.NET Framework中称为元数据堆,在.NET Core及.NET 5+中则在元数据中),这是一个非堆内存区域,用于存储类型信息和静态数据。
  • 生命周期:静态变量的生命周期从类被加载到CLR时开始,直到应用程序域卸载或应用程序终止。
  • 访问:静态变量可以通过类名直接访问,无需创建类的实例,如 MyClass.myStaticVariable。当然,你也可以通过实例引用访问静态变量,但这并不常见,且不推荐这样做。
  • 初始化:静态变量可以在类的静态构造函数中初始化,或者直接在声明时初始化。

3.利用递归,写个文件目录遍历,打印出文件名、扩展名、文件大小

using System;
using System.IO;

class DirectoryTraversal
{
    // 递归函数遍历目录
    public static void TraverseDirectory(DirectoryInfo directory)
    {
        // 获取当前目录下的所有文件
        FileInfo[] files = directory.GetFiles();
        foreach (FileInfo file in files)
        {
            // 打印文件名、扩展名和大小
            Console.WriteLine($"File Name: {file.Name}, Extension: {file.Extension}, Size: {file.Length} bytes");
        }

        // 获取当前目录下的所有子目录
        DirectoryInfo[] subDirs = directory.GetDirectories();
        foreach (DirectoryInfo subDir in subDirs)
        {
            // 递归调用遍历子目录
            TraverseDirectory(subDir);
        }
    }

    public static void Main()
    {
        try
        {
            // 指定要遍历的根目录
            string rootPath = @"D:\AADJ\app\Microsoft Visual Studio\2022\repos\DJConsoleProject";
            DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);

            // 开始遍历目录
            TraverseDirectory(rootDirectory);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }
}

4.简述访问修饰符有几种,各有什么不同?

(1)public

  • 含义:公共访问修饰符。被标记为public的成员可以从任何地方访问,包括其他文件、程序集甚至不同的应用程序。
  • 适用范围:全局访问,没有限制。

(2)private

  • 含义:私有访问修饰符。被标记为private的成员只能在其声明所在的类中访问,即使是在派生类中也无法访问。
  • 适用范围:仅限于声明该成员的类内部。

(3)protected

  • 含义:受保护的访问修饰符。被标记为protected的成员可在声明该成员的类及其派生类中访问。
  • 适用范围:声明该成员的类和所有派生类。
  • 注意:可以多继承(一个类可以被多个类继承,但一个类只能有1个父类),但不可以多级继承(只有该类的子类可以访问,子类的子类不能访问)

(5)internal

  • 含义:内部访问修饰符。被标记为internal的成员只能在同一程序集(assembly)内的代码中访问。
  • 适用范围:同一程序集内。

(6)protected internal

  • 含义:受保护的内部访问修饰符。结合了protectedinternal的特点,被标记为protected internal的成员可以在同一程序集内以及从任何派生类中访问。
  • 适用范围:同一程序集内和所有派生类。

5.重点比较public、protected、private的区别

public成员可以从任何地方访问,protected成员可以从基类和派生类访问,而private成员只能从声明它的类内部访问。

例子:

public class BaseClass
{
    public int pc;
    protected int pd;
    private int pe;

    public void pcm()
    {
        Console.WriteLine("public method");
    }

    protected void pdm()
    {
        Console.WriteLine("protected method");
    }

    private void pem()
    {
        Console.WriteLine("private method");
    }
}

public class DerivedClass:BaseClass
{
    public void accessMember()
    {
        pc = 10;  //直接访问父类的public属性
        pd = 20;  //直接访问父类的protected属性
        //pe = 30  //报错:private方法只能在声明它的类中访问

        pcm();  //直接访问父类的public方法
        pdm();  //直接访问父类的protected方法
        //pem(); //报错:private方法只能在声明它的类中访问
    }
}

public Program
{
    static void Main()
    {
        DerivedClass dc = new DerivedClass();
        dc.accessMember(); //外部类通过派生类去访问基类

        dc.pc = 100; //public属性无论在哪里都可以调用
        dc.pd = 20;  //报错:外部类不能直接访问protected属性,只能子类去访问

        dc.pcm();  //public方法无论在哪里都可以调用
        dc.pdm();  //报错:外部类不能直接访问protected方法,只能子类去访问
    }
}

  • 37
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值