.NET中的结构和类有什么区别?
当前回答
结构是实际值-它们可以为空,但不能为空
这是正确的,但是也要注意,从.NET2开始,结构支持Nullable版本,C#提供了一些语法糖,使其更易于使用。
int? value = null;
value = 1;
其他回答
类中声明的事件通过锁(this)自动锁定其+=和-=访问,以使其线程安全(静态事件根据类的类型锁定)。结构中声明的事件没有自动锁定其+=和-=访问。结构的锁(this)无法工作,因为只能锁定引用类型表达式。创建结构实例不能导致垃圾收集(除非构造函数直接或间接创建引用类型实例),而创建引用类型的实例会导致垃圾收集。结构始终具有内置的公共默认构造函数。类DefaultConstructor{静态空隙Eg(){直接yes=新的直接();//始终编译正常InDirect可能=新InDirect();//如果构造函数存在且可访问,则编译//...}}这意味着结构总是可实例化的,而类可能不是,因为它的所有构造函数都可以是私有的。类不可实例化{private NonInstantiable()//确定{}}结构Direct{private Direct()//编译时错误{}}结构不能有析构函数。析构函数只是对象的重写。伪装完成,结构作为值类型,不受垃圾收集的影响。结构Direct{~Direct(){}//编译时错误}InDirect类{~InDirect(){}//编译正常}~Indirect()的CIL如下所示:.method家族hidebysig虚拟实例无效Finalize()cil已管理{// ...}//方法结束间接::Finalize结构是隐式密封的,类不是。结构不能是抽象的,类可以。结构不能在其构造函数中调用:base(),而没有显式基类的类可以。结构不能扩展另一个类,类可以。结构不能声明类可以声明的受保护成员(例如,字段、嵌套类型)。结构不能声明抽象函数成员,抽象类可以。结构不能声明虚函数成员,类可以。结构不能声明密封的函数成员,类可以。结构不能声明重写函数成员,类可以。此规则的一个例外是,结构可以重写System.Object的虚拟方法,即Equal()、GetHashCode()和ToString()。
除了访问说明符的基本区别,以及上面提到的几个区别之外,我还想添加一些主要区别,包括上面提到的一些区别,以及带有输出的代码示例,这将提供对引用和值的更清晰的了解
结构:
是值类型,不需要堆分配。内存分配不同,存储在堆栈中适用于小型数据结构影响性能,当我们将值传递给方法时,我们会传递整个数据结构,所有数据都传递给堆栈。构造函数只返回结构值本身(通常在堆栈上的临时位置),然后根据需要复制该值每个变量都有自己的数据副本,其中一个变量的操作不可能影响另一个变量。不支持用户指定的继承,它们隐式继承自类型对象
类别:
参考类型值存储在堆中存储对动态分配对象的引用构造函数是用new运算符调用的,但它不会在堆上分配内存多个变量可以引用同一对象对一个变量的操作可能会影响另一个变量引用的对象
代码示例
static void Main(string[] args)
{
//Struct
myStruct objStruct = new myStruct();
objStruct.x = 10;
Console.WriteLine("Initial value of Struct Object is: " + objStruct.x);
Console.WriteLine();
methodStruct(objStruct);
Console.WriteLine();
Console.WriteLine("After Method call value of Struct Object is: " + objStruct.x);
Console.WriteLine();
//Class
myClass objClass = new myClass(10);
Console.WriteLine("Initial value of Class Object is: " + objClass.x);
Console.WriteLine();
methodClass(objClass);
Console.WriteLine();
Console.WriteLine("After Method call value of Class Object is: " + objClass.x);
Console.Read();
}
static void methodStruct(myStruct newStruct)
{
newStruct.x = 20;
Console.WriteLine("Inside Struct Method");
Console.WriteLine("Inside Method value of Struct Object is: " + newStruct.x);
}
static void methodClass(myClass newClass)
{
newClass.x = 20;
Console.WriteLine("Inside Class Method");
Console.WriteLine("Inside Method value of Class Object is: " + newClass.x);
}
public struct myStruct
{
public int x;
public myStruct(int xCons)
{
this.x = xCons;
}
}
public class myClass
{
public int x;
public myClass(int xCons)
{
this.x = xCons;
}
}
输出
Struct Object的初始值为:10
内部结构方法Struct对象的内部方法值为:20
结构对象的方法调用值为:10
类对象的初始值为:10
内部类方法类对象的内部方法值为:20
类对象的方法调用值为:20
在这里,您可以清楚地看到按值调用和按引用调用之间的区别。
每个项目的简短摘要:
仅限班级:
可以支持继承是引用(指针)类型引用不能为空每个新实例的内存开销
仅结构:
无法支持继承是值类型按值传递(如整数)不能有空引用(除非使用了Nullable)每个新实例没有内存开销-除非“装箱”
类和结构:
复合数据类型通常用于包含一些具有某种逻辑关系的变量吗可以包含方法和事件可以支持接口
首先,结构是通过值而不是引用传递的。结构适用于相对简单的数据结构,而类通过多态性和继承从体系结构的角度来看具有更大的灵活性。
其他人可能会比我给你更多的细节,但当我所追求的结构很简单时,我会使用结构。
类的实例存储在托管堆上。“包含”实例的所有变量都只是对堆上实例的引用。将对象传递给方法会导致传递引用的副本,而不是对象本身。
结构(从技术上讲,值类型)存储在使用它们的任何地方,很像原始类型。运行时可以随时复制内容,而无需调用自定义的复制构造函数。将值类型传递给方法涉及复制整个值,同样无需调用任何自定义代码。
C++/CLI名称使这种区别更加明显:“ref class”是第一个类,“value class”是第二个类。C#使用的关键字“class”和“struct”只是必须学习的东西。
推荐文章
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- 接口方法的最终参数-有什么意义?
- c#中有任何连接字符串解析器吗?
- MSBuild路径
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- 如何使用try catch进行异常处理是最佳实践
- .NET中字节的字面后缀?
- 如何处理AccessViolationException
- c#忽略证书错误?
- 如何在Visual Studio中找到堆栈跟踪?
- 如何强制LINQ Sum()返回0而源集合是空的
- 什么时候使用Struct vs. OpenStruct?