C#类和结构详解

目录
  • 一.类
    • 1.数据成员
    • 2.函数成员
      • (1)方法
      • (2)属性(property)
      • (3)构造函数
    • 3.只读字段
  • 二.匿名类型
  • 三.结构(struct)
  • 四.类和结构的区别
    • 1.结构是值类型
    • 2.结构和继承
    • 3.结构的构造函数
  • 五.弱引用
  • 六.部分类
  • 七.静态类
  • 八.Object类
  • 九.扩展方法

类和结构实际上都是创建对象(实例)的模版,每个对象都包含数据,并提供了处理和访问数据的方法。

类定义了类的每个对象可以包含什么数据和功能。

class PhoneCus

    {

        public const string DaySend = "Mon";

        public int CusId;

    }

结构与类的区别是它们在内存中的存储方式,访问方式和它们的一些特性(稍后详细介绍它们的区别)。

较小的数据类型使用结构可提高性能,在语法上,比较类似,主要区别是使用关键字struct代替class来声明结构。

struct PhoneCusStruct
    {
        public const string DaySend = "Mon";
        public int CusId=;
    }

对于类和结构,都是用new来声明实例:这个关键字创建对象并对其进行初始化。

PhoneCus myCus = new PhoneCus();
PhoneCusStruct  myCus2 = new PhoneCusStruct();

上面的例子,类和结构的字段值都默认0.

一.类

类中的数据和函数称为类的成员(数据成员和函数成员)。

1.数据成员

数据成员是包含类的数据————字段,常量和事件的成员。数据成员可以是静态数据。类成员总是实例成员,除非用static显示声明。

2.函数成员

函数成员提供了操作类中数据的某些功能,包括方法,属性,构造函数,终结器,运算符以及索引。

(1)方法

*C#区分函数和方法。C#中函数包含上述提到的。

*给方法传递参数

参数可以通过引用或值传递给方法。在变量通过引用传递给方法时,被调用的方法得到的就是这个变量,准确的説就是指向内存中变量的指针。所以在方法内对变量进行的任何改变在方法退出后仍然有效。

而如果变量通过值传递给方法,被调用的方法得到的是变量的一个相同副本,也就是说,在方法退出后,对变量的修改会丢失。

对于复杂的数据类型,按引用传递的效率更高,因为在按值传递时,必须复制大量的数据。

注意字符串的行为方式有所不同,因为字符串是不可变的,所以字符串无法采用一般引用类型的行为方式。在方法调用中,对字符串所做的改变都不会影响原始字符串。

*ref参数

像上面所説,值类型通过值传递变量是默认的。但也可以迫使值参数通过引用传递给方法。为此要使用ref关键字。这样该方法对变量所做的任何改变都会影响原始值。

static void SomeFunction(int[] ints,ref int i)
        {
            ints[0] = 100;
            i = 100;
        }

在调用该方法的时候,必须添加ref关键字。

SomeFunction(ints, ref i);
*out参数

C#要求变量在被引用前必须用一个初始值进行初始化。但使用out关键字来初始化可以简化C# 编译器所坚持的输入参数的初始化。

在方法的输入参数前加上out前缀时,传递给该方法的变量可以不初始化。而且该变量通过引用传递,所以在从被调用的方法中返回时,对应方法对该变量进行的任何改变都会保留下来。

在调用该方法时,仍需要使用out关键字:

static void SomeFunction(int[] ints,out int i)
         {
                ints[0] = 100;
                 i = 100;
         }

        SomeFunction(ints, out i);
*命名参数

参数一般需要按定义的顺序传递给方法。命名参数允许按任意顺序传递。

string FullName(string firstName,string lastName)
    {
        renturn firstName+" " +lastName;
    }

调用方法:

FullName("John","Doe");
      FullName(lastName:"Doe",firstName:"John");
*可选参数

参数也可以是可选的。必须为可选参数提供默认值。可选参数还必须是方法定义的最后一个参数。

void TestMethod(int notOption,int option = 10)
        {
            Console.WriteLine( notOption + option);
        }
*方法的重载

C#支持方法的重载————方法的几个版本有不同的签名(方法名相同,但参数的个数和/或类型不同)。

class MathTest
          {
             public int Value;
             public int GetSquare()
             {
                    return Value*Value;
             }

             public  int GetSquare(int x)
             {
                return x*x;
             }
          }

重载方法在参数方面的一些限制:

两个方法不能仅在返回类型上有区别;

两个方法不能仅根据参数是声明为ref还是out来区分。

在任何语言中,对于方法重载,如果调用了错误的重载方法,就有可能出现运行错误。(后面讨论如何避免这些错误)。

(2)属性(property)

属性是一个方法或一对方法,在客户端看来,它是一个字段。

public string  SomeProperty
        {
            get
           {
                return "value";
            }
            set
            {
                //设置属性值
            }
        }

get访问器不带任何参数,且必须返回属性声明的类型。也不应为set访问器指定任何显示参数,编译器会

假定它带一个参数,器类型也许属性相同,并表示为value.

private int age
        public int  Age
        {
            get
            {
                return age;
            }
            set
            {
                age = valeu;
            }
        }

注意所用的命名约定,采用C#的区分大小写模式,使用相同的名称,但公有属性采用大写形式命名,如果存在一个等价的私有字段,则采用小写形式命名。

一些开发人员喜欢使用把下划线作为前缀的字段名,如_age,这会为识别字段提供极大的便利。

*只读和只写属性

在属性定义中省略set访问器,就会创建只读属性。这样客户端代码只可以读取该属性的值,但不能设置值。

private int age
        public int  Age
        {
            get
            {
                return age;
            }
        }

同样在属性定义中省略get访问器,就会创建只写属性。

*属性的访问修饰符

C#允许给属性的gei和set访问器设置不同的访问修饰符,所以属性可以有公有的get访问器和受保护的set访问器。

在gey和set访问器中,必须有一个具有属性的访问级别(公有)。

*自动实现的属性

如果属性的set和get访问器中没有任何逻辑,就可以使用自动实现的属性。这种属性会自动实现后背成员变量。

public int  Age
        {
            get;
            set;
        }

不需要声明private int age;,编译器会自动创建它。

使用自动实现的属性,就不能在属性设置中验证属性的有效性。但必须有两个访问器,不能把属性设置为只读或只写。

  public int  Age
  {
    get;//报错
  }

  但是,每个访问器的访问级别可以不同,
  public int  Age
  {
    get;
    private set;
  }

(3)构造函数

声明基本构造函数就是声明一个与包含的类同名的方法,但该方法没有返回值。

  public class MyClass
  {
    public MyClass()
    {

    }
    //
  }

一般情况下,如果没有提供任何构造函数,编译器会在后台创建一个默认的构造函数。这是一个基本的构造函数,它只能把所有的成员字段初始化为标准的默认值。这通常就足够了,否则需要编写自己的构造函数。

构造函数的重载与其它方法的规则相同。可以为构造函数提供任意多的的重载,只要它们的签名有明显区别。

public class MyClass
        {
            public MyClass()
            {

            }

            public MyClass(int i )
            {
                / /
            }
            //
        }

如果提供了带参数的构造函数,编译器就不会自动提供默认的构造函数。只有在没有定义任何构造函数的时候,编译器才会自动提供默认的构造函数。

public class MyNum
        {
            private int number;
            public MyNum(int number)
            {
                this.number  =number;
            }
        }

一般使用this关键字区分成员字段和同名的参数。

如果试图使用无参数的构造函数实例化对象就会报错:

MyNum num = new MyNum();//报错

可以把构造函数定义为private或protected,这样不相关的类就不能访问它们:

public class MyNum
        {
            private int number;
            private MyNum(int number)
            {
                this.number  =number;
            }
        }

上述例子没有为MyNum定义为任何公有或受保护的构造函数。这就使MyNum不能使用new运算符在外部代码中实例化,但可以在MyNum类中编写一个公有静态属性或方法,以实例化该类。

这在下面两种情况下受有用的:

类仅用作某些静态成员或属性的容器,因此永远不会实例化它。

希望类仅通过某个静态成员函数来实例化。

*静态构造函数

C#可以给类编写无参数的静态构造函数。这种构造函数只执行一次,而前面的构造函数是实例构造函数,只要创建类的对象,就会

执行它。

  class MyClass
  {
    static MyClass()
    {

    }
  }

编写静态构造函数的一个原因是,类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。

.NET运行库不能确保什么时候执行静态构造函数,所以不能把要求在某个特定时刻执行的代码放在静态构造函数中。也不能预计不同类的静态构造函数按照什么顺序执行。但是可以确保静态构造函数最多运行一次,就在代码引用类之前调用它。

在C#中,通常在第一次调用类的任何成员之前执行静态构造函数。

注意,静态构造函数没有访问修饰符,其它C#代码从来不调用它,但在加载类时,总是由.NET运行库调用它,所以像public,private这样的访问修饰符就没有任何意义。出于同样原因,静态构造函数不能带任何参数,一个类也只能有一个静态构造函数。很显然,静态构造只能访问累的静态成员,不能访问类的实例成员。

无参数的实例构造函数与静态构造函数可以在同一个类中同时定义。虽然参数列表相同,但这并不矛盾,因为在加载类的时候执行静态构造函数,在创建实例时执行实例构造函数,所以何时执行哪个构造函数不会有冲突。

如果任何静态字段有默认值,就在调用静态构造函数之前指定它们。

下面演示静态构造函数的用法:

class MainEntryPoint
{
     static void Main()
     {

      Console.WriteLine("UserPreference:BackColor is " + UserPreference.BackColor.ToString());
     }
}

class UserPreference
{
     public static readonly Color BackColor;
     static UserPreference()
     {
      BackColor = Color.Red;
     }

    private UserPreference()
    {

    }
}

该静态变量在静态构造函数中进行初始化。

*从构造函数中调用其它构造函数

有时,在一个类中有几个构造函数,这些构造函数包含一些共同的代码。

  class Car
  {
    private string des;
    private int nWheels;
    public Car(string des,int nWheels)
    {
      this.des = des;
      this.nWheels = nWheels;
    }

    public Car(string des)
    {
      this.des = des;
        this.nWheels = 4;
      }
  }

这两个构造函数初始化了相同的字段,显然最好把所有的代码放在一个地方。C#有一个特殊的语法,称为构造函数初始化器,可以实现这个目的。

  class Car
  {
    private string des;
    private int nWheels;
    public Car(string des,int nWheels)
    {
      this.des = des;
        this.nWheels = nWheels;
      }
    public Car(string des):this(des,4)
    {

      }
  }

这里,this关键字仅调用参数最匹配的那个构造函数。构造函数初始化器在构造函数的函数体之前执行。

C#构造函数初始化器可以包含对同一个类的另一个构造函数的调用,也可以包含对直接基类的构造函数的调用,使用同样的语法,但应用base关键字代替this.初始化器中不能有多个调用。

3.只读字段

常量是一个包含不能修改的值的变量。但常量不必满足所有的要求。有时需要一些一些变量,其值不应改变,但在运行之前其值是未知的。C#为这种情形提供了另一种类型的变量:只读字段(readonly)。

readonly关键字比const灵活得多,允许把一个字段设置为常量,但可以执行一些计算,以确定它得初始值。

其规则是可以在构造函数中给只读字段赋值,但不能在其它地方赋值。只读字段还可以是一个实例字段,类的每个实例可以有不同得值。

与const不同,如果要把只读字段设置为静态,就必须显示得声明它。

二.匿名类型

var关键字用于表示隐式类型化得变量。var和new关键字一起使用时,可以创建匿名类型。

匿名类型只是一个继承自Object且没有名称的类。

var caption = new {FirstName = "John",LastName="Doe"};

这会生成一个包含FirstName,LastName属性的对象。

创建另一个对象:

var doctor = new {FirstName = "James",LastName="Mc"};

caption和doctor的类型就相同,可以设置caption = doctor

如果设置的值来自于另一个对象,就可以简化初始化器。

var doctor = new {caption.FirstName,caption.LastName};

这些对象的类型名未知。编译器为类型“伪造”了一个名称,但只有编译器才能使用它。

三.结构(struct)

如果仅需要一个小的数据结构,此时类提供的功能多余我们需要的功能,由于性能原因,最好使用结构。

结构是值类型,它们存储在栈中或存储为内联(inline)(如果它们是存储在堆中的另一个对象的一部分),其生存期的限制与简单的数据类型一样。

  • *结构不支持继承。
  • *对于结构,构造函数的方式与类有一些区别。编译器总是提供一个无参数的默认构造函数,它是不允许替换的。
  • *使用结构可以指定字段如何在内存中布局(后面详细介绍)

结构实际上是把数据项组合在一起,有时大多数字段都声明为public。严格来说,这与编写.net代码的规则相反(字段应总是私有的(除const字段外),并由公有属性封装)。但是,对于简单的结构,公有字段是可以接受的编程方式。

四.类和结构的区别

1.结构是值类型

虽然结构是值类型,但在语法上可以把它当作类来处理。

struct PhoneCusStruct
    {
        public const string DaySend = "Mon";
        public int CusId=0;
    }

    PhoneCusStruct phoneCusStruct = new PhoneCusStruct();
    phoneCusStruct.CusId=3;

因为结构是值类型,所以new运算符与类和其它引用类型的工作方式不同。new运算符并不分配堆中的内存,而只是调用相应的构造函数,根据传送给它的参数,初始化所有的字段。

对于结构编写下面的代码是合法的:

  PhoneCusStruct phoneCusStruct;
  phoneCusStruct.CusId=3;

结构遵循其它数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。在结构上调用new运算符,或者给所有的字段分别赋值,结构就完全初始化了。

如果结构定义为类的成员字段,在初始化包含的对象时,该结构会自动初始化为0.

结构是会影响性能的值类型,但根据使用结构的方式,这种影响可能是正面的,也可能是负面的。正面的影响是为结构分配内存时,速度很快,因为它们将内联或保存在栈中。在结构超出了作用域被删除时,速度也很快,不需要等待垃圾回收。负面影响是,只要把结构作为参数来传递或者把一个结构赋予另一个结构,结构的内容就会被复制,而对于类只复制引用。这样就会有性能损失,根据结构的大小,性能损失也不同。

注意,结构主要用于小的数据结构。当把结构作为参数传递给方法时,应把它作为ref参数传递,以避免性能损失(这样只传递了结构在内存中的地址)。

2.结构和继承

结构不能从一个结构中继承。唯一的例外是对应的结构(和其它类型一样)最终派生于类System.Object。因此结构也可以访问Object的方法。

在结构中也可以重写Object中的方法——如ToString()方法。

结构的继承链是:每个结构派生于System.ValueType类,System.ValueType类有派生于System.Object。ValueType并没有给Object添加任何成员,但提供了一些更适合结构的实现方法。

注意,不能为结构提供其它基类。

3.结构的构造函数

为结构定义构造函数的方式与类的方式相同,但不允许定义无参数的构造函数。因为在一些罕见的情况下,.NET运行库不能调用用户提供的自定义无参数构造函数,因此Microsoft干脆采用禁止在C#的结构内使用无参数的构造函数。

默认构造函数会隐式的把字段初始化,即使提供了其它带参数的构造函数,也会先调用它。提供字段的初始值也不能绕过默认构造函数。下面代码会编译错误:

  struct PhoneCusStruct
  {
    public int CusId =0;
  }

如果PhoneCusStruct声明为一个类,就不会报错了。

另外,可以像类那样为结构提供Close()或Dispose()方法。

五.弱引用

在应用程序代码内实例化一个类或结构时,只要有代码引用这个对象,就会形成强引用。这意味着垃圾回收器不会清理这个对象使用的内存,一般而言这是好事,因为可能需要引用这个对象,但是如果这个对象很大,而且不经常访问。这个时候可以创建对象的弱引用。

弱引用允许创建和使用对象,但在垃圾回收器运行时,就会回收对象并释放内存。由于存在潜在的Bug和性能问题,一般不会这么做,但在特定情况下使用是合理的。

弱引用使用WeakReference类创建。因为对象可能在任意时刻被回收,所以引用该对象前必须确认它的存在。  

class MainEntryPoint
{
    static void Main()
    {
        // Instantiate a weak reference to MathTest object
        WeakReference mathReference = new WeakReference(new MathTest());
        MathTest math;
        if(mathReference.IsAlive)
        {
            math = mathReference.Target as MathTest;
            math.Value = 30;
            Console.WriteLine(
            "Value field of math variable contains " + math.Value);
            Console.WriteLine("Square of 30 is " + math.GetSquare());
        }
        else
        {
            Console.WriteLine("Reference is not available.");
        }
        GC.Collect();

        if(mathReference.IsAlive)
        {
            math = mathReference.Target as MathTest;
        }
        else
        {
            Console.WriteLine("Reference is not available.");
        }
    }
}

// Define a class named MathTest on which we will call a method
class MathTest
{
    public int Value;

    public int GetSquare()
    {
        return Value*Value;
    }

    public static int GetSquareOf(int x)
    {
        return x*x;
    }

    public static double GetPi()
    {
        return 3.14159;
    }
}

六.部分类

partial关键字允许把类,结构,接口放在多个文件中。

partial关键字的用法:把partial放在class,struct,interface前面即可。

如果声明类时使用了下面的关键字,这些关键字就必须应用于同一个类的所有部分:

public,private,protected,internal,abstract,sealed,new,一般约束

在把部分类编译后,类的成员和继承等会合并。

七.静态类

如果类只包含静态的方法和属性,该类就是静态的。静态类在功能上与使用私有静态构造函数创建的类相同。都不能创建静态类的实例。

使用static关键字,编译器可以检查用户是否给该类添加了实例成员。如果是,就会生成一个编译错误。这可以确保不创建静态类的实例。

  static class PhoneCusStruct
  {
    public static void GetPhene()
    {

    }
  }

调用:PhoneCusStruct.GetPhene();

八.Object类

前面提到,所有的.NET类都派生自System.Object类.实际上,如果在定义类的时候没有指定基类,编译器就会自动假定这个类派生自Object类。其实际意义在于,除了自己定义的方法和属性等外,还可以访问Object定义的许多公有的和受保护的成员方法。这些方法可用于自己定义的其它类中。

System.Object的方法:

  • 1.GetHashCode():如果对象放在名为映射(散列表或字典)的数据结构中,就可以使用这个方法。处理这些结构的类使用该方法可以确定把对象放在结构的什么地方。如果希望把类用作字典的一个键,就需要重写这个方法。(后面介绍字典时会详细介绍)
  • 2.Equals()和ReferenceEquals()方法:后面会详细介绍。
  • 3.Finalize()方法:在引用对象作为垃圾被回收以清理资源时调用它。Object中实现的Finalize()方法实际上什么也没有做,因而被垃圾回收器忽略。如果对象拥有对未托管资源的引用,则在该对象被删除时,就需要删除这些引用,此时一般要重写Finalize()方法。垃圾收集器不能直接删除这些未托管资源的引用,因为它只负责托管的资源,于是它只能依赖用户提供的Finalize()方法。垃圾收集器不能直接删除这些未托管资源的引用,因为它只负责托管的资源,于是它只能依赖用户提供的Finalize方法。
  • 4.GetType()方法:这个方法返回从System.Type派生的类的一个实例。这个对象可以提供对象成员所属类的很多信息。System.Type还提供了.NET的反射技术的入口。
  • 5.MemberwiseClose()方法:这个方法复制对象,并返回对副本的一个引用(对于值类型,就是一个装箱的引用)。得到的副本是一个浅表复制,即它复制了类中的所有值类型。如果类包含内嵌的引用,就只复制引用,而不复制引用的对象。这个方法是受保护的,所以不能用于复制外部的对象(可以复制父类的对象)。该方法不是虚方法,所以不能重写。
  • 6.ToString()方法:是获取对象的字符串表示的一种快捷方式。当只需要快速获取对象的内容,以进行调试时,就可以使用这个方法。在数据的格式化方面,它几乎没有提供选择,比如:在原则上日期可以表示为许多不同格式,但DateTime.ToString()没有在这方面提供任何选择。这个方法是虚方法,可以重写这个方法以返回这些类型的正确字符串表示。

九.扩展方法

如果有类的源码,继承就可以给对象添加方法。但如果没有源代码,则可以使用扩展方法,它允许改变一个类,但不需要该类的源代码。

扩展方法是静态方法,它是类的一部分,但实际上没有放在类的源代码中。假定PhoneCusStruct类需要一个Add()方法,但不能修改源代码,就可以创建一个静态类,把Add()方法添加为一个静态方法:

  public static class PhoneExtension
  {
    public static void Add(this PhoneCusStruct phoneCusStruct,string phone)
    {
    //
    }
  }

注意扩展方法的第一个参数是要扩展的类型,它放在this关键字的后面。这告诉编译器,这个方法是PhoneCusStruct类型的一部分。在这个例子中,PhoneCusStruct是要扩展的类型。在扩展方法中,可以访问所扩展类型的所有公有方法和属性。

调用:

PhoneCusStruct p =new PhoneCusStruct();
p.Add();//即使方法是静态方法,也需要使用实例方法的语法。

如果扩展方法与类中的某个方法同名,就不会调用扩展方法。类中已有的任何实例方法优先。

到此这篇关于C#类和结构的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#基础语法:结构和类区别详解

    结构和类很相似,也可以包含数据成员和函数成员,但是与类不同,结构是一种值类型,(我们可以理解为一种特殊的值类型所以不存在继承的问题)为其分配数据不需要从托管堆中分配存储器.结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是对相应对象的一个引用.  下面总结一下结构和类的不同: 1.结构是值类型,对结构类型的变量赋值将创建所赋值的一个副本. 2.结构实例的默认值不是null,而是具有默认值的初始值. 3.在结构和类中this的意义不一样. 4.结构不支持继承(所以结构成员的声明可访问

  • c#结构和类的相关介绍

    我们不关心对象内部是怎么实现的,我们关心的是他提供给我什么接口,有什么操作.从技术上来说,结构属于值类型,而类属于引用类型.结构不能指定继承基类类型,类可以.不过结构和类都能实现接口. 一.应用场合结构的应用场合: 一.自定义数据类型,数据成员是公开的,提供工具函数. 二.抽象的数据类型,数据成员是密封的,提供相关的数据操作函数. 总之,都是围绕数据作文章. 类的应用场合: 一.提供一组类,形成一个有机整体,形成一个系统,类数据成员是密封的,只提供相互通信的函数接口. 类主要通过不同的类组成一个

  • 轻松学习C#的结构和类

    类和结构是.NET Framework中的同样类型系统的两种基本构造.两者在本质上都属于数据结构,封装这一组整体作为一个逻辑单位的数据和行为.数据和行为是该类或结构的"成员",它们包含着各自的方法,属性和事件等.        结构        结构是C#程序员用来定义自己的值类型的最普遍的机制.结构比枚举更强大,因为它提供方法,字段,操作符和访问控制等.        结构与类很相似,都表示可以包含数据成员和函数成员的数据结构.但是,与类不同,结构是一种值类型,并且不需要堆分配.结

  • C#枚举类型与结构类型实例解析

    本文以C#实例讲解了枚举类型与结构类型的用法,程序主要是通过个人电话本演示枚举类型与结构类型的用法,具体代码如下所示: using System; class ID { //定义枚举类型 public enum Sex { male, female };//注意别忘了这里的分号 //定义电话本的结构类型 public struct TelBook { public string name; public Sex sex;//性别类型为枚举类型 public string number; } //

  • 基于c# 类、接口、结构的联系与区别详解

    一.C#类与结构的差别1. 值类型与引用类型结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建更多的值类型类是引用类型:引用类型在堆上分配地址堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象.所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋

  • C#中类与结构的区别实例分析

    类与结构是C#程序设计中基本的数据类型,而初学者往往不能很好的分清二者之间的区别.本文就以附带实例形式加以说明.具体如下: 一.基本概念: 类:引用类型,存储在堆中,栈中存储引用地址,在方法的传输中只是传输地址的引用,修改指向的对象会影响原有对象的值,传输中消耗内存小. 结构:值类型,存储在堆栈中,传输过程中传输整个对象的副本,修改指向对象的值不会影响原有的对象,传输中消耗内存大. 二.实例代码如下: class Program { static void Main(string[] args)

  • 浅析C#中结构与类的区别

    一. 结构:值类型,存储在堆栈中,位于计算机的内存逻辑区域中 类   :引用类型,存储在堆中,位于计算机内存的不同逻辑位置 二. 较小的数据使用结构: 将一个结构值传递到方法时,传递的是整个数据结构: 传递一个类,实际上是将引用传递到对象,即只有内存地址: 对结构修改,改变的是结构的副本,这是值类型工作方式的定义:传递值的副本: 传递一个引用到类本身意味着在类中修改值,实际上改变的是原始对象: 三.代码例子 1.新建 PointClass.cs namespace StructAndClass

  • 深入c# 类和结构的区别总结详解

    类和结构的区别:1.一个是引用类型一个是值类型Class是引用类型,继承自System.Object类Struct是值类型,继承自System.ValueType类,因此不具有多态性因为结构是值类型,所以结构之间赋值可以创建新的结构,复制包含结构的变量时,讲复制所有的数据,对新的副本所作的修改都不会改变旧副本的数据,而类是引用类型,类之间的赋值只是复制引用.2. 继承性的区别Class支持继承,可以继承自类和接口,是完全可扩展的,除非声明sealed.否则类可以继承自其它的类的接口,自身也能被继

  • C#类和结构详解

    目录 一.类 1.数据成员 2.函数成员 (1)方法 (2)属性(property) (3)构造函数 3.只读字段 二.匿名类型 三.结构(struct) 四.类和结构的区别 1.结构是值类型 2.结构和继承 3.结构的构造函数 五.弱引用 六.部分类 七.静态类 八.Object类 九.扩展方法 类和结构实际上都是创建对象(实例)的模版,每个对象都包含数据,并提供了处理和访问数据的方法. 类定义了类的每个对象可以包含什么数据和功能. class PhoneCus { public const

  • java类的组成结构详解

    目录 成员变量 方法 构造器 代码块 成员变量 成员变量便是在类中定义的变量. 例如这样: public class POP { int a = 1; } 而成员变量又分为两种,一种是被static所修饰的类变量,他归类所有,一种是没有被static修饰的实例变量,他归对象所有. 如下: public class POP { int a = 1; static int b = 1; } 正如字面上的意思,归类所有的变量b,他能在类的外部,直接通过POP.b的形式进行操作. 如下程序: publi

  • Python循环结构详解

    一.内容简介 使用while循环编写重复执行的语句 使用哨兵值控制循环 使用for循环实现计数器控制 使用break.continue控制循环 二.while循环 注意:循环控制时不要使用浮点型来比较等值 i = 1 # 循环变量的初值 while i < 10: # 循环变量的判断 print("当前第", i, "次循环") i += 1 # 循环变量的更新 PyCharm调试示例 # PyCharm中的调试 # 1. 设置断点:debug->调试

  • C语言类的双向链表详解

    目录 前言 双向链表的定义 双向链表的创建 节点的创建 双向链表节点查找 双向链表的插入 双向链表的节点删除 双向链表的删除 总结 前言 链表(linked list)是一种这样的数据结构,其中的各对象按线性排列.数组的线性顺序是由数组下标决定的,然而于数组不同的是,链表的各顺序是由链表中的指针决定的. 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循

  • C++ Queue队列类模版实例详解

    目录 1.队列的介绍 2.代码实现 3.测试运行 总结 1.队列的介绍 队列的定义 队列(Queue)是一种线性存储结构.它有以下几个特点: 按照"先进先出(FIFO, First-In-First-Out)"方式进出队列. 队列只允许在"队首"进行取出操作(出队列),在"队尾"进行插入操作(入队列 ) 队列实现的方式有两种 基于动态数组实现 基于链表形式实现 队列需要实现的函数 T dequeue() : 出队列,并返回取出的元素 void e

  • ASP.NET MVC模式中应用程序结构详解

    目录 一.App_Data 二.App_Start 三.Content 四.Controllers 五.font 六.Models 七.Scripts 八.Views 九.Web.config 1.根目录下面的Web.config文件 2.Views文件夹下面的Web.config 十.Global.asax 在上一篇文章中,讲解了一些MVC的概念,并且创建了第一个ASP.NET MVC项目,这篇文章将讲解ASP.NET MVC程序中的代码解构,新创建的MVC应用程序解构如下图所示: 一.App

  • Java项目的目录结构详解

    一个java web项目 目录分为两个部分 ① Web应用的根目录下子目录WEB-INF,里面内容不能被客户端访问的,包括专用Web应用程序软件,包括Servlet类文件.部署描述符web.xml.外部库以及其他任何由此应用程序使用的专用文件. ② 所有位于WEB-INF之外的文件都被看作是公共的,客户端是可以访问到的.资源包括HTML页面.JSP页面和图像等. 一.Common包 Common用来封装一些常用的公共方法. 二.Dao包 Dao主要用来封装对数据库的新增,删除,查询,修改.叫做数

  • 基于java涉及父子类的异常详解

    java中的异常涉及到父子类的问题,可以归纳为一句话:子类的构造函数抛出的异常必须包含父类的异常,子类的方法可以选择抛出"范围小于等于"父类的异常或不抛出异常. 1. 为什么构造函数必须抛出包含父类的异常? 在<thingking in java>中有这么一段话: 异常限制:当覆盖方法时,只能抛出在基类方法的异常说明中列出的那些异常 异常限制对构造器不起作用,你会发现StormyInning的构造器可以抛出任何异常,而不必理会基类构造函数所抛出的异常.然而因为必须构造函数必

  • spring的几个重要类和接口(详解)

    1. datasource接口是javax.sql包下的接口,不是spring,是javax.sql下的 datasource接口有个重要的方法getConnection()方法 Connection getConnection(String username, String password) throws SQLException; 那些spring支持的数据库连接池,都是实现了Datasource接口 比如下面是阿里的DruidDatasource数据库连接池源码,它就是实现了dataso

  • 玩转JavaScript OOP - 类的实现详解

    概述 当我们在谈论面向对象编程时,我们在谈论什么? 我们首先谈论的是一些概念:对象.类.封装.继承.多态. 对象和类是面向对象的基础,封装.继承和多态是面向对象编程的三大特性. JavaScript提供了对象却缺乏类,它不能像C#一样能显式地定义一个类. 但是JavaScript的函数功能非常灵活,其中之一就是构造函数,结合构造函数和原型对象可以实现"类". 对象和类的概念 对象 "对象"是面向对象编程中非常重要的一个概念,一个对象是一个"东西"

随机推荐