C#中定义内部类

类的定义是可以嵌套的,即在类的内部还可以定义其他的类。类内声明的类称为内部类(internal class)或者嵌套类(nested class)。在编译单元或命名空间内声明的类称为顶级类或者非嵌套类型(non-nested class)。

比如,下面的List类中定义了一个private类型的内部类Node:

public class List

{

   // private内部类

   private class Node

   {

      public object Data;

      public Node Next;

      public Node(object data, Node next)

      {

        this.Data = data;        // this是Node类的对象

        this.Next = next;

      }

   }

   private Node first = null;

   private Node last = null;

  

   // public方法

   public void AddToFront(object o) {...}

   public void AddToBack(object o) {...}

   public object RemoveFromFront() {...}

   public object RemoveFromBack() {...}

   public int Count { get {...} }

}

内部类和包含它的那个类并不具有特殊的关系。在内部类内,this不能用于引用包含它的那个类的实例成员,而只能引用内部类自己的成员。比如,上述代码中的内部类Node中的this只能引用Node的对象,而不能代表List类的对象。

如果类A是类B的内部类,当需要在内部类A的内部访问类B的实例成员时,可以在类B中将代表类B的实例的this作为一个参数传递给内部类A的构造函数,这样就可以实现在类A的内部对类B的访问。比如:

// NestedClass1.cs

// 内部类的示例

using System;

class Wrapper

{

    string name = "Wrapper";

    public void F()

    {

        // 构造内部类实例时,传入包含内部类的类的this实例

        Nested n = new Nested(this);

        n.G();

    }

    public class Nested

    {

        Wrapper thisW;        // 用于保存外部类的实例

        public Nested(Wrapper w)

        {

            thisW = w;

        }

        public void G()

        {

            Console.WriteLine(thisW.name);

        }

    }

}

class Test

{

    static void Main()

    {

        Wrapper w = new Wrapper();

        w.F();

    }

}

Wrapper实例创建了一个Nested实例,并将代表它自己的this传递给Nested的构造函数,这样,就可以对Wrapper的实例成员进行后续访问了。

内部类可以访问包含它的那个类可访问的所有成员,包括该类自己的具有private和protected声明可访问性的成员。比如:

// NestedClass2.cs

// 内部类的示例

using System;

class Wrapper

{

    protected string name = "Wrapper";

    private void F()

    {

        Console.WriteLine("Wrapper.F()");

    }

    public class Nested

    {

        public void G()

        {

            Wrapper w = new Wrapper();

             Console.WriteLine(w.name);

            w.F();

        }

    }

}

class Test

{

    static void Main()

    {

        Wrapper.Nested n = new Wrapper.Nested();

        n.G();

    }

}

上述代码中,类Wrapper包含内部类Nested。在Nested内,方法G引用在Wrapper中定义的protected字段name和private方法F()。

内部类的完全限定名为S.N,其中S是声明了N类的那个类的完全限定名。

非嵌套类可以具有public或internal访问修饰符,默认的访问修饰符是internal。但是,内部类具有5种访问修饰符(public、protected internal、protected、internal或private)中的任何一种,而且与其他类成员一样,默认的已访问修饰符是private。

内部类的可访问域受包含它的类的访问修饰符和它自身的访问修饰符的限制。内部类的可访问域至少为包含它的类体。内部类可访问域是声明它的类的可访问域的子集。

内部类的成员的可访问域受包含内部类的类访问修饰符、内部类的访问修饰符和它自身的访问修饰符的限制。内部类成员的可访问域是内部类的可访问域的子集。比如,

internal class B

{

   public static int X;

   internal static int Y;

   private static int Z;

   public class C

   {

      public static int X;

      internal static int Y;

      private static int Z;

   }

   private class D

   {

      public static int X;

      internal static int Y;

      private static int Z;

   }

}

上述代码中的类和成员的可访问域分别为:

— B、B.X、B.Y、B.C、B.C.X和B.C.Y的可访问域是定义类B的程序。

— B.Z和B.D的可访问域是B的代码体,包括B.C和B.D的代码体。

— B.C.Z的可访问域是B.C的代码体。

— B.D.X和B.D.Y的可访问域是B的代码体,包括B.C和B.D的代码体。

— B.D.Z的可访问域是B.D的代码体。

当内部类的成员与定义它的类的成员重名时,内部类成员会隐藏外部类的成员。比如,在上面的例子中,在B.C内直接使用X、Y、Z指的是B.C.X、B.C.Y、B.C.Z,而不是B.X、B.Y、B.Z。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C#,我们可以通过自定义异常类来处理应用程序可能出现的异常情况。自定义异常类需要继承自`System.Exception`类。 以下是一个简单的自定义异常类的实现示例: ```csharp public class MyException : Exception { public MyException() { } public MyException(string message) : base(message) { } public MyException(string message, Exception innerException) : base(message, innerException) { } } ``` 在上面的代码,我们定义了一个名为`MyException`的自定义异常类。该类继承自`System.Exception`类,并提供了三个构造函数。第一个构造函数是默认的构造函数,第二个构造函数接受一个字符串参数,用于指定异常消息,第三个构造函数接受两个参数,第一个参数是异常消息,第二个参数是内部异常。 通过自定义异常类,我们可以在应用程序抛出符合我们需求的异常,这样可以更好地处理应用程序可能出现的异常情况。以下是一个示例: ```csharp public class MyClass { public void DoSomething(int input) { if (input < 0) { throw new MyException("Input cannot be negative."); } } } class Program { static void Main(string[] args) { MyClass myClass = new MyClass(); try { myClass.DoSomething(-1); } catch (MyException ex) { Console.WriteLine(ex.Message); } } } ``` 在上面的代码,我们在`MyClass`类的`DoSomething`方法检查输入是否为负数,如果是负数,则抛出`MyException`异常。在`Main`方法,我们捕获了`MyException`异常,并输出了异常消息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值