C# 从结构继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15408667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inherit from struct
提问by user2110292
I am try to figure out what is the problem whit my code. I have this code:
我试图弄清楚我的代码有什么问题。我有这个代码:
public struct MyStructA
{
public MyStructA(string str)
{
myString= str;
}
public string myString;
}
public struct MyStructB: MyStructA
{
public string myReversString;
}
And i get this error:
我得到这个错误:
Error at compile time: Type 'MyStructA' in interface list is not an interface
I don't understand why? the .net not implemnet struct like class?
我不明白为什么?.net 不像类那样实现结构?
采纳答案by One Man Crew
A struct Is Implicitly Sealed
一个结构体被隐式密封
According to this link:
根据此链接:
Every struct in C#, whether it is user-defined or defined in the .NET Framework, is sealed–meaning that you can't inherit from it. A struct is sealed because it is a value type and all value types are sealed.
C# 中的每个结构,无论是用户定义的还是在 .NET Framework 中定义的,都是密封的——这意味着您不能从它继承。结构是密封的,因为它是值类型并且所有值类型都是密封的。
A struct can implement an interface, so it's possible to see another type name following a colon, after the name of the struct.
结构体可以实现接口,因此可以在结构体名称之后的冒号后面看到另一个类型名称。
In the example below, we get a compile-time error when we try to define a new struct that inherits from the one defined above.
在下面的示例中,当我们尝试定义一个继承自上面定义的结构的新结构时,会出现编译时错误。
public struct PersonName
{
public PersonName(string first, string last)
{
First = first;
Last = last;
}
public string First;
public string Last;
}
// Error at compile time: Type 'PersonName' in interface list is not an interface
public struct AngryPersonName : PersonName
{
public string AngryNickname;
}
回答by Adil
Struct does not support inheritance, if you need you have to use class, see msdn
Struct 不支持继承,如果需要必须使用 class,请看msdn
There is no inheritance for structs as there is for classes. A struct cannot inherit from another struct or class, and it cannot be the base of a class. Structs, however, inherit from the base class Object. A struct can implement interfaces, and it does that exactly as classes do.
结构没有继承,类有继承。结构不能从另一个结构或类继承,也不能作为类的基类。然而,结构继承自基类 Object。一个结构体可以实现接口,它和类完全一样。
回答by boli
Inheritance isn't alloweded between structs but structs can implement interfaces.
结构之间不允许继承,但结构可以实现接口。
回答by Soner G?nül
From MSDN
;
来自MSDN
;
There is no inheritance for structs as there is for classes. A struct cannot inherit from another struct or class, and it cannot be the base of a class. Structs, however, inherit from the base class Object. A struct can implement interfaces, and it does that exactly as classes do.
结构没有继承,类有继承。结构不能从另一个结构或类继承,也不能作为类的基类。然而,结构继承自基类 Object。一个结构体可以实现接口,它和类完全一样。
But remember, since structs are a value typeand they inherit System.ValueType
但请记住,由于结构是值类型并且它们继承System.ValueType
回答by Soner G?nül
Structs can implement an interface but they cannot inherit from another struct. For that reason, struct members cannot be declared as protected.
结构体可以实现接口,但不能从另一个结构体继承。因此,结构成员不能被声明为受保护的。
回答by supercat
Value types in .NET are weird in that they defined though they are classes derived from a special class called ValueType
. For every value type there is a heap object type which behaves like a class object that derives from ValueType
, but a value-type storage location holds a collection of bytes which either represents a primitive value, or the concatenation of the bytes necessary to hold all of its public and private fields.
.NET 中的值类型很奇怪,因为它们定义了尽管它们是从一个名为ValueType
. 对于每个值类型,都有一个堆对象类型,它的行为类似于派生自 的类对象ValueType
,但值类型存储位置保存一组字节,这些字节要么表示原始值,要么表示保存所有必需的字节的串联它的公共和私人领域。
Since value type storage locations just hold the bytes necessary to represent their values, and hold neither type information nor any reference to an object which would hold type information, the code which uses a value type storage location must know exactly what it is.
由于值类型存储位置只保存表示其值所必需的字节,既不保存类型信息,也不保存对将保存类型信息的对象的任何引用,因此使用值类型存储位置的代码必须确切知道它是什么。
Conventional inheritance requires that objects hold information about their own type, but there is no provision via which value types could do so.
传统的继承要求对象保存关于它们自己类型的信息,但没有规定值类型可以这样做。
It would be conceptually possible (and useful) for .NET to allow some limited forms of value-type inheritance with some special rules, such that while a BaseStructure
variable could only hold a BaseStructure
and couldn't hold a DerivedStructure
. One could define a StructureUser<T> where T:BaseStructure
, and such class or method could accept any derivative of BaseStructure
and use those members--including fields--which were common to the base type.
从概念上讲,.NET 允许某些具有某些特殊规则的有限形式的值类型继承是可能的(并且有用),例如,虽然BaseStructure
变量只能包含 aBaseStructure
而不能包含DerivedStructure
. 可以定义一个StructureUser<T> where T:BaseStructure
,这样的类或方法可以接受BaseStructure
并使用这些成员的任何派生类——包括字段——这些成员对于基类型是通用的。
Unfortunately, it would be difficult to define rules for generics in such a way as to behave consistently in permitted scenarios and yet not break any existing code.
不幸的是,很难为泛型定义规则,使其在允许的场景中保持一致的行为,同时又不破坏任何现有代码。
For example, within a class Foo<T,U> where T:U
it's always possible to store a T
to a variable of type U
, even if U
is a value type (i.e. because value types are sealed, T
and U
are guaranteed to be the sametype). If U
could be an inheritable value type and T
could be a derivative, such a guarantee would not hold.
例如,在一个类中Foo<T,U> where T:U
,总是可以将 a 存储T
到 type 的变量U
,即使U
是值类型(即因为值类型是密封的,T
并且U
保证是相同的类型)。如果U
可以是可继承的值类型并且T
可以是派生的,则这样的保证将不成立。
Given the difficulties associated with such inheritance, a more useful alternative would be to provide a safe (even if limited) means via which a property could expose a byref or a const-byref (a byref is the thing which is passed when a parameter uses a ref
qualifier).
鉴于与此类继承相关的困难,更有用的替代方法是提供一种安全(即使有限)的方式,通过该方式属性可以公开 byref 或 const-byref(byref 是在参数使用时传递的内容)一个ref
限定词)。
Such a feature would remove the unavoidable semantic distinction between fields and properties, and depending upon how it was implemented could offer some major advantages even when used with classes (e.g. it could allow for efficient mixing of immutable and mutable types).
这样的特性将消除字段和属性之间不可避免的语义区别,并且根据它的实现方式,即使与类一起使用,也可以提供一些主要优势(例如,它可以允许不可变和可变类型的有效混合)。
回答by Riki
There are actually a few good reasons:
其实有几个很好的理由:
Structs have no 'Type'
...unless they are 'boxed' into an object.
An
object
on the other hand has two "header" fields in the normal CLR where the type is stored (and some GC- and locking info). Adding that would change the size of the structs, and make their size unpredictable (because some runtimes might chose to add that information differently, for example the mono runtime adds more "header" information to its objects than the .net framework runtime, or at least did so in the past)This boxing is actually what happens when you try to assign a struct to an interface field it implements. So it would be possible in theory, but then all your structs would be boxed, and that'd be really bad for performance reasons.
Typing and fixed size
To show why specifically inheriting structs would be a huge problem lets make a simple example.
Consider two structs:
struct MyBaseStruct { public int A; }
and a hypotheticalstruct MyDerivedStruct : MyBaseStruct { public int B; }
.Now what would happen when I call
var array = new MyBaseStruct[10];
?? How much size would the runtime allocate for that?The assignment
array[0] = new MyDerivedStruct();
would be troublesome, on 32bit systems it would probablywrite to the first ANDthe second slot as well.Even if you'd try to "collect" all derived types it wouldn't work, what if you load another dll that defines yet another struct that derives from your base-struct?
结构没有“类型”
...除非它们被“装箱”成一个物体。
一个
object
在另一方面具有在其中类型存储在正常CLR(和一些GC-和锁定信息)两个“标题”字段。添加这会改变结构的大小,并使它们的大小不可预测(因为某些运行时可能会选择以不同的方式添加该信息,例如,与 .net 框架运行时相比,mono 运行时为其对象添加了更多的“头”信息,或者在过去至少这样做)当您尝试将结构分配给它实现的接口字段时,实际上会发生这种装箱。所以理论上这是可能的,但是你所有的结构都会被装箱,这对于性能来说真的很糟糕。
打字和固定大小
为了说明为什么专门继承结构会是一个大问题,让我们举一个简单的例子。
考虑两个结构体:
struct MyBaseStruct { public int A; }
和一个假设的struct MyDerivedStruct : MyBaseStruct { public int B; }
.现在当我打电话时会发生什么
var array = new MyBaseStruct[10];
?运行时会为此分配多少大小?分配
array[0] = new MyDerivedStruct();
会很麻烦,在 32 位系统上,它可能也会写入第一个和第二个插槽。即使您尝试“收集”所有派生类型,它也行不通,如果您加载另一个 dll,该 dll 定义了另一个从您的基础结构派生的结构,该怎么办?
I personally find it pretty important to know the actual issues that probably led the designers to the decision in the first place. But of course a one could also just say "because the designers of the language made it so!"or "because that's what the C# language specification says":P
我个人认为了解可能导致设计师做出决定的实际问题非常重要。但是当然一个人也可以说“因为语言的设计者这样做了!” 或“因为这就是 C# 语言规范所说的”:P