C#结构泛型构造函数

C#结构泛型构造函数,c#,generics,constructor,struct,C#,Generics,Constructor,Struct,使用此代码: struct Foo<T1> { public T1 Item1 { get; private set; } public Foo(T1 item1) { Item1 = item1; } } structfoo { 公共T1项1{get;私有集;} 公共食品(T1项目1) { 第1项=第1项; } } 我遇到这个错误: 在将控件返回给调用方之前,必须完全分配自动实现的属性“Foo.Item1”的支持字段。考虑从构造

使用此代码:

struct Foo<T1>
{
    public T1 Item1 { get; private set; }

    public Foo(T1 item1)
    {
        Item1 = item1;
    }
}
structfoo
{
公共T1项1{get;私有集;}
公共食品(T1项目1)
{
第1项=第1项;
}
}
我遇到这个错误:

在将控件返回给调用方之前,必须完全分配自动实现的属性“Foo.Item1”的支持字段。考虑从构造函数初始化器调用默认构造函数。< /P> 我的问题是,为什么在调用构造函数后属性
Item1
没有完全赋值

编辑:将
set
更改为
private set
,因为此问题与可变性无关。

在此添加
this()

public Foo(T1 item1) : this()
{
    Item1 = item1;
}

这是因为您正在为属性赋值,而编译器无法推断该属性只为变量赋值;它可以在初始化实例之前执行其他操作,这是不允许的,因为该结构可能有垃圾数据。所以你必须先用默认构造函数初始化它,然后做你想做的事。

请不要做易变结构。@Lambert不仅容易产生坏的易变结构,而且很难正确使用它们。@Lambert:易变结构在C#中是一种“最糟糕的做法”。说“只要使用正确就好”是似是而非的逻辑;问题是你必须知道如何正确使用它们,而大多数人却不知道。可变值类型会在代码中留下小炸弹,只是等待一些毫无戒心的维护程序员通过执行一些看似琐碎的重构,将可变值类型视为引用类型,从而意外地引爆炸弹。@Lambert:是的,在重建不可变树结构时,通常必须重建脊椎,这是(lg n)。对于一个包含(比如)两万个项目的树来说,这是15次分配。这与您获得的好处相比几乎没有什么区别,即,当每个新根指针都有99.9%的内容从以前的版本中回收时,您可以在撤消重做缓冲区中以极低的成本拥有大量过去的编辑。@Lambert:我之所以使用不可变链表,正是因为它们在我需要插入的地方插入成本低廉。如果我需要插入到列表的中间,那么我不会使用不可变链表,我会使用不可变可链接的deque——如果你碰巧需要的话,我的博客上会有一个实现。当然,如果我使用的是C风格的API它明确地期望变异作为你与它通信的方式,那么我会说这是一个写得很糟糕的API,但我会按照它的设计使用它。@Lambert:问题是,为什么编译器看不到显而易见的东西?在其他情况下,编译器在流分析方面做得相当好。C#中的值类型不允许这样做,因为没有保证在某些情况下会调用它们,例如在生成数组时。@Vlad:事实上,编译器可能有一条规则,即如果调用的属性是autoprop,那么我们知道它除了设置字段之外没有任何作用。但是,有两件事。(1)这就是工作,我们几乎没有把自动道具放到C#3中;它们几乎不符合日程安排,(2)这意味着将自动道具更改为“正常”道具会给你带来一个奇怪的错误,你必须把它改成this()拜访你的构造器。我同意这有点笨拙,但至少它遵循了自动道具和常规道具一样的原则。@Eric:与常规道具案例的一致性是一个合理的原因(至少对我来说),谢谢。@Danjen:没有内在的原因,这只是他们设计语言和运行时的结果。