[英]Can you have a class in a struct?
Is it possible in C# to have a Struct with a member variable which is a Class type? 在C#中是否可以使用具有类型类型的成员变量的Struct? If so, where does the information get stored, on the Stack, the Heap, or both?
如果是这样,信息存储在哪里,堆栈,堆,或两者?
Yes, you can. 是的你可以。 The pointer to the class member variable is stored
on the stack
with the rest of the struct's values, and the class instance's data is stored on the heap. 指向类成员变量
的指针
与结构的其余值一起存储
在堆栈中
,类实例的数据存储在堆上。
Structs can also contain class definitions as members (inner classes). 结构也可以包含类定义作为成员(内部类)。
Here's some really useless code that at least compiles and runs to show that it's possible: 这是一些真正无用的代码,至少编译并运行以显示它是可能的:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyStr m = new MyStr();
m.Foo();
MyStr.MyStrInner mi = new MyStr.MyStrInner();
mi.Bar();
Console.ReadLine();
}
}
public class Myclass
{
public int a;
}
struct MyStr
{
Myclass mc;
public void Foo()
{
mc = new Myclass();
mc.a = 1;
}
public class MyStrInner
{
string x = "abc";
public string Bar()
{
return x;
}
}
}
}
The class content gets stored on the heap. 类内容存储在堆上。
A reference to the class (which is almost the same as a pointer) gets stored with the struct content. 对类的引用(与指针几乎相同)与struct内容一起存储。 Where the struct content is stored depends on whether it's a local variable, method parameter, or member of a class, and whether it's been boxed or captured by a closure.
存储结构内容的位置取决于它是局部变量,方法参数还是类的成员,以及它是否被闭包装箱或捕获。
If one of the fields of a struct is a class type, that field will either hold the identity of a class object or else a null referece. 如果结构的某个字段是类类型,则该字段将保留类对象的标识 ,或者保留null引用。 If the class object in question is immutable (eg
string
), storing its identity will effectively also store its contents. 如果所讨论的类对象是不可变的(例如
string
),则存储其标识也将有效地存储其内容。 If the class object in question is mutable, however, storing the identity will be an effective means of storing the contents if and only if the reference will never fall into the hands of any code which might mutate it once it is stored in the field . 但是,如果所讨论的类对象是可变的,那么存储该标识将是一种有效的存储内容的方法, 当且仅当该引用永远不会落入任何代码的手中,这些代码一旦存储在字段中就可能使其变异 。
Generally, one should avoid storing mutable class types within a structure unless one of two situations applies: 通常,应避免在结构中存储可变类类型,除非以下两种情况之一适用:
Note that scenario #1 is pretty common with generic types; 请注意,场景#1在泛型类型中非常常见; for example, it's very common to have a dictionary whose "values" are the identities of mutable objects;
例如,有一个字典的“值”是可变对象的身份是很常见的; enumerating that dictionary will return instances of
KeyValuePair
whose Value
field holds that mutable type. 枚举该字典将返回
KeyValuePair
的实例,其Value
字段包含该可变类型。
Scenario #2 is less common. 场景#2不太常见。 There is alas no way to tell the compiler that struct methods other than property setters will modify a struct and their use should thus be forbidden in read-only contexts;
没有办法告诉编译器除了属性设置器之外的结构方法将修改结构,因此在只读上下文中应禁止它们的使用; one could have a struct that behaved like a
List<T>
, but with value semantics, and included an Add
method, but an attempt to call Add
on a read-only struct instance would generate bogus code rather than a compiler error. 一个可以有一个行为类似于
List<T>
,但是具有值语义,并且包含一个Add
方法,但是尝试在只读结构实例上调用Add
会产生伪代码而不是编译器错误。 Further, mutating methods and property setters on such structs will generally perform rather poorly. 此外,这种结构上的变异方法和属性设定器通常表现得相当差。 Such structs can be useful are when they exist as an immutable wrapper on an otherwise-mutable class;
当这些结构作为一个不可变的包装器存在于其他可变类中时,它们可能是有用的; if such a struct is never boxed, performance will often be better than a class.
如果这样的结构永远不会被装箱,那么性能往往比一个类好。 If boxed exactly once (eg by being cast to an interface type), performance will generally be comparable to a class.
如果只装箱一次(例如通过铸造到接口类型),性能通常可以与一个类别相比。 If boxed repeatedly, performance can be much worse than a class.
如果重复加框,性能可能比一类差。
It's probably not a recommended practice to do so: see http://msdn.microsoft.com/en-us/library/ms229017(VS.85).aspx 这可能不是推荐的做法:请参阅http://msdn.microsoft.com/en-us/library/ms229017(VS.85).aspx
Reference types are allocated on the heap, and memory management is handled by the garbage collector.
引用类型在堆上分配,内存管理由垃圾收集器处理。
Value types are allocated on the stack or inline and are deallocated when they go out of scope.
值类型在堆栈或内联中分配,并在超出范围时释放。
In general, value types are cheaper to allocate and deallocate.
通常,值类型分配和释放更便宜。 However, if they are used in scenarios that require a significant amount of boxing and unboxing, they perform poorly as compared to reference types.
但是,如果它们用于需要大量装箱和拆箱的场景,则与参考类型相比,它们的性能很差。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.