我对C#相当陌生,我有一个问题困扰了我一段时间。
[当我学习C#时,我被告知一个类不应包含很多变量,因为那样一来,读取变量(或从中调用方法)会很慢。
有人告诉我,当我访问C#类中的变量时,它将从内存中读取整个类以读取变量数据,但这对我来说听起来很奇怪和错误。
例如,如果我有这个课程:
public class Test
{
public int toAccess; // 32 bit
private byte someValue; // 8 bit
private short anotherValue; // 16 bit
}
然后从main访问它:
public class MainClass
{
private Test test;
public MainClass(Test test)
{
this.test = test;
}
public static void Main(string[] args)
{
var main = new MainClass(new Test());
Console.WriteLine(main.test.toAccess); // Would read all 56 bit of the class
}
}
我的问题是:真的吗?访问变量时是否读取了整个类?
对于classes,这实际上没有任何区别;您总是只处理参考和该参考的偏移量。通过参考很便宜。
[当它[[确实]]开始重要时是与结构。免责声明:您 可能 任何用作值的地方struct MyBigStruct {
// lots of fields here
}
void Foo() {
MyBigStruct x = ...
Bar(x);
}
void Bar(MyBigStruct s) {...}
然后在调用堆栈上的结构。同样,只要将本地用于存储(假设编译器未将其本地化):Bar(x)
时,我们copy
MyBigStruct x = ...
MyBigStruct asCopy = x;
但是!我们可以通过传递来解决这些问题。在当前版本的C#中,最合适的做法是使用reference
in
,ref readonly
和ref
:readonly struct MyBigStruct {
// lots of readonly fields here
}
void Foo() {
MyBigStruct x = ...
Bar(x); // note that "in" is implicit when needed, unlike "ref" or "out"
ref readonly MyBigStruct asRef = ref x;
}
void Bar(in MyBigStruct s) {...}
现在有个实际副本。这里的所有内容都涉及对原始零
x
的引用。它是readonly
的事实意味着运行时知道它可以信任参数上的in
声明,而无需该值的防御性副本。ref
,您也可以使用readonly
做类似的事情,但是您需要知道,如果Bar
突变了值(故意或作为副作用),这些更改将对Foo
可见。