博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
结构和类
阅读量:5953 次
发布时间:2019-06-19

本文共 2800 字,大约阅读时间需要 9 分钟。

       结构和类很相似,也可以包含数据成员和函数成员,但是与类不同,结构是一种值类型,(我们可以理解为一种特殊的值类型所以不存在继承的问题)为其分配数据不需要从托管堆中分配存储器。结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是对相应对象的一个引用。


 

下面总结一下结构和类的不同:

结构是值类型,对结构类型的变量赋值将创建所赋值的一个副本。

结构实例的默认值不是null,而是具有默认值的初始值。

在结构和类中this的意义不一样。

结构不支持继承(所以结构成员的声明可访问性不能是protected,protected internal,结构中的函数成员不能是abstract 或者virtual,所以在结构中override修饰符只适用于重写从System.ValueType继承的方法)但是可以实现接口。

在结构中实例字段声明中不能含有变量的初始值设定项

在结构中不能声明无参数的实例构造函数。

在结构中不能声明析构函数。

 


 

测试区别特性代码:

 
using System;
namespace StructAndClass
{
    struct SPoint
    {
        public int x, y;
        public SPoint(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
    class  CPoint
        {
            public int x, y;
            public CPoint(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }
    class Test
    {
        public static void Main()
        {
            SPoint sp1 = new SPoint(2, 5);
            Console.WriteLine("结构/sp1初始值:");
            Console.WriteLine("sp1.x={0}", sp1.x);
            SPoint sp2 = sp1;
            Console.WriteLine("sp1=sp2后:");
            Console.WriteLine("sp1.x={0}");
            Console.WriteLine("sp1.x={0}", sp1.x);
            Console.WriteLine("sp2.x={0}", sp2.x);
            sp1.x = 5;
            Console.WriteLine("再次改变sp1的值后:");
            Console.WriteLine("sp1.x={0}", sp1.x);
            Console.WriteLine("sp2.x={0}", sp2.x);
            Console.WriteLine("============================");
            CPoint cp1 = new CPoint(2,5);
            Console.WriteLine("类/cp1初始值:");
            Console.WriteLine("cp1.x={0}", cp1.x);
            CPoint cp2 = cp1;
            Console.WriteLine("cp1=cp2后:");
            Console.WriteLine("cp1.x={0}", cp1.x);
            Console.WriteLine("cp2.x={0}", cp2.x);
            cp1.x = 5;
            Console.WriteLine("再次改变cp1的值后:");
            Console.WriteLine("cp1.x={0}", cp1.x);
            Console.WriteLine("cp2.x={0}", cp2.x);
            Console.ReadKey();
        }
    }
}

 

 


 

对于结构,即使没有new运算符声明的结构变量也是有效的,结构虽然不能声明无参数的实力构造函数,但是它其实隐式的包含了一个无参数的构造函数:而且在结构的所有字段没有明确赋值之前,不能调用结构的实例函数成员。在结构的构造函数中应该给所有的字段赋值。例如:


 
struct
DC
   
{
       
public
int
x
,
y;
       
public
int
X
       
{
           
set
           
{
               
x
=
value;
           
}
           
get
           
{
               
return
x;
           
}
       
}
       
public
int
Y
       
{
           
set
           
{
               
y
=
value;
           
}
           
get
           
{
               
return
y;
           
}
       
}
       
public
DC(
int
x
,
int
y)
       
{
           
this
.
x
=
x;
           
this
.
y
=
y;
       
}
   
}
   
struct
RDC
   
{
       
public
int
x
,
y;
       
public
int
X
       
{
           
set
           
{
               
x
=
value;
           
}
           
get
           
{
               
return
x;
           
}
       
}
       
public
int
Y
       
{
           
set
           
{
               
y
=
value;
           
}
           
get
           
{
               
return
y;
           
}
       
}
       
public
RDC(
int
x
,
int
y)
       
{
           
this
.
x
=
x;
           
this
.
y
=
y;
       
}
   
}
   
class
Test
   
{
       
public
static
void
Main()
       
{
           
DC
dc
=
new
DC();
           
dc
.
x
=
3;
           
dc
.
y
=
5;
           
Console
.
WriteLine(
"已经对x,y初始化后:");
           
Console
.
WriteLine(
"此时可以访问和修改dc.X={0}的值"
,
dc
.
X);
           
Console
.
WriteLine(
"我在这里创建了一个DC的复制结构RDC/n并且不对x,y初始化就会报错");
           
RDC
rdc;
             
rdc
.
y
=
5;
//可以编译通过
             
rdc
.
X
=
3;
//这里就会出错,不能编译通过
           
Console
.
WriteLine(
"=======test over================");
         }
    }

            在结构的实例构造函数内,this 相当于一个结构类型的 out 参数,(必须在内部对它明确赋值)而在结构的实例函数成员内,this 相当于一个结构类型的 ref 参数。在这两种情况下,this 本身相当于一个变量,因而有可能对该函数成员调用所涉及的整个结构进行修改(如对 this 赋值,或者将 this 作为 ref 或 out 参数传递)。例如:(引用上面的例子)


 
struct
DC
   
{
       
public
int
x
,
y;
       
public
int
X
       
{
           
set
           
{
               
x
=
value;
           
}
           
get
           
{
               
return
x;
           
}
       
}
       
public
int
Y
       
{
           
set
           
{
               
y
=
value;
           
}
           
get
           
{
               
return
y;
           
}
       
}
       
public
DC(
int
x
,
int
y)
       
{
          
X
=
x;
//这里就是错的
          
Y
=
y;
//会提示没有给this对象的所有字段赋值
       
}
   
}

转载地址:http://lfoxx.baihongyu.com/

你可能感兴趣的文章
web安全问题分析与防御总结
查看>>
React 组件通信之 React context
查看>>
Centos下基于Hadoop安装Spark(分布式)
查看>>
3D地图的定时高亮和点击事件(基于echarts)
查看>>
mysql开启binlog
查看>>
设置Eclipse编码方式
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>
并查集hdu1232
查看>>
Mysql 监视工具
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
nginc+memcache
查看>>
Numpy中的random模块中的seed方法的作用
查看>>
关于jsb中js与c++的相互调用
查看>>
POJ-2251 Dungeon Master
查看>>
tortoisesvn的安装
查看>>
URAL 1353 Milliard Vasya's Function DP
查看>>
速读《构建之法:现代软件工程》提问
查看>>
Android onclicklistener中使用外部类变量时为什么需要final修饰【转】
查看>>
django中聚合aggregate和annotate GROUP BY的使用方法
查看>>