[根据答案和评论进行编辑和扩展]
我们有一个 public C#API,它使用没有任何构造函数的嵌套结构。 注意: public 表示它不是我们的,我们需要通过固定的序列化函数与它进行通信。
因此
public struct Inner {
public int f1;
public int f2;
public Inner(int _f1, int _f2)
{
this.f1 = _f1;
this.f2 = _f2;
}
};
public struct Outer {
public int z;
public Inner f;
public Outer (int _f1, int _f2, int _z)
{
this.f = new Inner(_f1, _f2);
this.z = _z;
}
};
public class HelloWorld
{
static public void Main ()
{
Outer someVar = new Outer(4,5,6);
给定的类型没有Inner
和Outer
构造函数。
我建议我们添加构造函数(如上所述),因为初始化变得相当繁琐。实际的结构比显示的大得多,导致数十个
someVar.f.f1 = initialzier
然而,我团队的一些成员认为我们不允许更改API'
这有官方的立场吗?
这里通过官方我不是指人类约定/最佳实践,而是指C#语义;即可以在C#struct
中添加构造函数来更改struct
布局吗?
同样相关的问题是内部结构上的new
或构造函数初始化一个临时位置,然后将其复制到外部结构中,还是将它原位初始化到外部结构中?
上面的代码中有2个new
。根据@supercat的回答,存储分配可能会也可能不会被优化掉。有没有办法保证?
[基本上我缺少C指针指向内部的能力 struct并将其传递给初始化函数]
另请注意,{/ 1}}应该/不应该使用,因此不讨论。因此,它可能用于历史可能与C等互操作 我们的代码需要与之互操作的另一方的原因。
答案 0 :(得分:1)
结构构造函数在语义上等同于修改this
的结构成员函数,除了C#编译器将转向:
someVar = new someStructType(this, that, theOther);
进入:
var temp = default(someStructType);
temp..ctor(this, that, theOther);
someVar = temp;
或
someVar..ctor(this, that, theOther);
和 - 在后一种情况下 - 编译器不会坚持在调用someVar
方法之前必须初始化.ctor
(这样会破坏构造函数的点)。
后者效率更高,但编译器只会在认为时使用它,后者将等同于前者。请注意,有一些场景,特别是涉及混合语言代码,其中C#行为将显着影响程序语义,但在大多数情况下行为是可观察的,编译器将使用前者。
从语法的角度来看,构造函数调用看起来最像是一个返回结构类型的函数。但是,这样的函数通常需要在临时中构建一个新结构,然后让调用者将它复制到所需的位置,这与构造函数有时不同,后者有时可以直接写入新变量。
答案 1 :(得分:0)
[基本上我缺少C能够将指针指向内部结构并将其传递给初始化函数]
据我所知,你可以在C#中做同样的事情:
public struct Inner {
public static void Init(out Inner value,int _f1,int _f2) {
value.f1=_f1;
value.f2=_f2;
}
public int f1;
public int f2;
}
public struct Outer {
public static void Init(out Outer value,int _f1,int _f2,int _z) {
Inner.Init(out value.f,_f1,_f2);
value.z=_z;
}
public int z;
public Inner f;
}
public class HelloWorld {
static public void Main() {
Outer someVar;
Outer.Init(out someVar,4,5,6);