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

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

问题描述

我知道,在.NET结构不支持继承,但它并不完全清楚的为什么的,他们以这种方式限制。

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

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

What technical reason prevents structs from inheriting from other structs?

推荐答案

值类型不支持继承的原因是因为阵列。

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

的问题是,对于性能和GC原因,值类型的数组存储内联。例如,给定新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#code:

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);

通过正常的转换规则,一个派生[] 可以转换为基地[] (或好或坏),所以如果你S /结构/班/克上面的例子中,它会编译和运行符合预期,没有问题。但是,如果基本派生是值类型和数组存储值内联,那么我们就有问题了。

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.

我们有一个问题,因为广场()不知道任何有关派生,它只会使用指针算法访问数组中的每个元素,以一定量递增(的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.)

因此​​,如果这种情况真的发生了,我们就会有内存损坏问题。具体而言,在广场()值[1] .A * = 2 实际进行修改值[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天全站免登陆