为什么结构不支持继承? [英] Why don't structs support inheritance?

查看:35
本文介绍了为什么结构不支持继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 .NET 中的结构不支持继承,但不清楚为什么它们以这种方式受到限制.

I know that structs in .NET do not support inheritance, but its not exactly clear why they are limited in this way.

什么技术原因阻止结构从其他结构继承?

What technical reason prevents structs from inheriting from other structs?

推荐答案

值类型不支持继承的原因是数组.

The reason value types can't support inheritance is because of arrays.

问题在于,出于性能和 GC 的原因,值类型的数组是内联"存储的.例如,给定 new FooType[10] {...},如果 FooType 是引用类型,则会在托管堆上创建 11 个对象(一个用于数组, 每个类型实例 10 个).如果 FooType 是值类型,则只会在托管堆上创建一个实例——用于数组本身(因为每个数组值都将与数组内联"存储).

The problem is that, for performance and GC reasons, arrays of value types are stored "inline". For example, given new FooType[10] {...}, if FooType is a reference type, 11 objects will be created on the managed heap (one for the array, and 10 for each type instance). If FooType is instead a value type, only one instance will be created on the managed heap -- for the array itself (as each array value will be stored "inline" with the array).

现在,假设我们有值类型的继承.当与数组的上述内联存储"行为结合时,会发生坏事,正如可以看到的 在 C++ 中.

Now, suppose we had inheritance with value types. When combined with the above "inline storage" behavior of arrays, Bad Things happen, as can be seen in C++.

考虑这个伪 C# 代码:

Consider this pseudo-C# code:

struct Base
{
    public int A;
}

struct Derived : Base
{
    public int B;
}

void Square(Base[] values)
{
  for (int i = 0; i < values.Length; ++i)
      values [i].A *= 2;
}

Derived[] v = new Derived[2];
Square (v);

按照正常的转换规则,Derived[] 可以转换为 Base[](无论好坏),所以如果你 s/struct/class/g对于上面的例子,它会按预期编译和运行,没有问题.但是如果 BaseDerived 是值类型,并且数组内联存储值,那么我们就有问题了.

By normal conversion rules, a Derived[] is convertible to a Base[] (for better or worse), so if you s/struct/class/g for the above example, it'll compile and run as expected, with no problems. But if Base and Derived are value types, and arrays store values inline, then we have a problem.

我们有一个问题,因为 Square()Derived 一无所知,它只会使用指针算术来访问数组的每个元素,递增一个常数 (sizeof(A)).程序集大概是这样的:

We have a problem because Square() doesn't know anything about Derived, it'll use only pointer arithmetic to access each element of the array, incrementing by a constant amount (sizeof(A)). The assembly would be vaguely like:

for (int i = 0; i < values.Length; ++i)
{
    A* value = (A*) (((char*) values) + i * sizeof(A));
    value->A *= 2;
}

(是的,这是一个令人讨厌的程序集,但关键是我们将以已知的编译时常量在数组中递增,而不知道正在使用派生类型.)

(Yes, that's abominable assembly, but the point is that we'll increment through the array at known compile-time constants, without any knowledge that a derived type is being used.)

所以,如果这真的发生了,我们就会遇到内存损坏问题.具体来说,在 Square() 中,values[1].A*=2实际上修改 values[0].B!

So, if this actually happened, we'd have memory corruption issues. Specifically, within Square(), values[1].A*=2 would actually be modifying values[0].B!

尝试调试那个

这篇关于为什么结构不支持继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆