值类型可以通过内联实现吗?
当我第一次看到 C# 中的值类型时,我想到的第一件事是“哇,多么伟大的优化”,第二件事是“我们真的需要一个新的语言构造吗?我们不能用注释来做到这一点吗? ”。
这个想法是,给定一个类,我们将像往常一样使用它
class A {int i;}
class B {
A m_a;
int F(A a) {m_a = a;}
}
一时兴起,我们将 A
更改为
[ValueType]
class A {int i;int j;}
并且编译器会自动将类 B
转换为请
class B {
#region A
int A_i;
int A_j;
#endregion
int F(/*A param*/int i,int j) {
#region A_assign
A_i = i;
A_j = j;
#endregion
}
记住,如果编译器不希望优化某些实例 - 则不必这样做。无论哪种方式都会起作用。
模板可能会出现问题,
int f<T>() {
T t; // how much stack should I allocate
}
但我不确定它比目前的情况糟糕多少。我实际上不确定现在会发生什么(f
是与 f
不同的函数吗?)。
When I first saw the value types in C#, the first thing I thought was "wow, what a great optimization", the second thing is, "do we really need a new language construct? can't we do that with annotations instead?".
The idea is, given a class, we'll use it as we always did
class A {int i;}
class B {
A m_a;
int F(A a) {m_a = a;}
}
On a whim we'll change A
to be
[ValueType]
class A {int i;int j;}
And the compiler will automatically convert class B
to be
class B {
#region A
int A_i;
int A_j;
#endregion
int F(/*A param*/int i,int j) {
#region A_assign
A_i = i;
A_j = j;
#endregion
}
Bear in mind, that if the compiler doesn't wish to optimize some instance - it doesn't have to. It would work either way.
It might arise problems with templates,
int f<T>() {
T t; // how much stack should I allocate
}
but I'm not sure it's much worse than the current situation. I'm actually not sure what happens now (is f<struct_of_100_bytes>
a different function than f<int>
?).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
现在想象一下继承。或者数组。或争论。或仿制药。或者实现一个接口。或者分配给对象/动态。
请记住,运行时支持多个编译器。
拥有特定的关键字(结构)而不是属性实际上并不是一个大的变化(事实上,就 CLI 而言,一切都称为类),但总体情况比您的示例复杂得多。
基本上,struct 几乎可以完成您提到的所有操作,并且适用于列出的所有场景。由于它通常(对于当地人)使用堆栈,因此它的行为已经很像您所描述的那样。
关于“独立功能”的问题;首先,泛型不是“模板”(它是运行时与编译时)。但是泛型为每个值类型获得一个 JIT,为每个引用类型获得一个 JIT(因为实际上:堆栈布局发生了变化。
Now imagine inheritance. Or arrays. Or arguments. Or generics. Or implementing an interface. Or assigning to object/dynamic.
And keep in mind that the runtime supports multiple compilers.
Having a specific keyword (struct) rather than an attribute is not really a big change (indeed, in terms of the CLI everything is called a class), but the overall situation is much more complex than your example.
Basically, struct does pretty-much everything you mention, and works in all the scenarios listed. Since it generally (for locals) uses the stack, it already behaves much like you describe.
Re the "separate function" question; firstly, generics are not "templates" (it is runtime vs compile-time). But generics get a JIT per value-type, and a single JIT per reference-type (because indeed: the stack layout changes.