C# 结构构造函数:";在将控件返回给调用方之前,必须完全分配字段。”;

C# 结构构造函数:";在将控件返回给调用方之前,必须完全分配字段。”;,c#,constructor,struct,C#,Constructor,Struct,下面是我正在尝试编写的结构: public struct AttackTraits { public AttackTraits(double probability, int damage, float distance) { Probability = probability; Distance = distance; Damage

下面是我正在尝试编写的结构:

  public struct AttackTraits
        {
            public AttackTraits(double probability, int damage, float distance)
            {
                Probability = probability;
                Distance = distance;
                Damage = damage;
            }

            private double probability;
            public double Probability
            {
                get
                {
                    return probability;
                }
                set
                {
                    if (value > 1 || value < 0)
                    {
                        throw new ArgumentOutOfRangeException("Probability values must be in the range [0, 1]");
                    }
                    probability = value;
                }
            }

            public int Damage { get; set; }

            public float Distance { get; set; }
        }
public结构攻击特征
{
公共攻击特征(双重概率,智力伤害,浮动距离)
{
概率=概率;
距离=距离;
损害=损害;
}
私人双重概率;
公共双重概率
{
得到
{
返回概率;
}
设置
{
如果(值>1 | |值<0)
{
抛出新ArgumentOutOfRangeException(“概率值必须在[0,1]范围内”);
}
概率=价值;
}
}
公共整数损坏{get;set;}
公共浮点距离{get;set;}
}
这将导致以下编译错误:

无法使用“this”对象 在分配其所有字段之前 到

必须输入“攻击特征.概率”字段 在完成控制之前完全分配 返回给打电话的人

自动生成的备份字段 实现属性 “攻击特征.伤害”必须完全禁用 在控件返回到之前分配 打电话的人。考虑调用 构造函数中的默认构造函数 初始化器

自动生成的备份字段 实现属性 “AttackTraits.Distance”必须完全为空 在控件返回到之前分配 打电话的人。考虑调用 构造函数中的默认构造函数 初始化器


我做错了什么?

您正在通过
probability
属性设置
probability
字段,但编译器不知道该属性设置了字段。。。所以需要显式初始化概率场本身

public AttackTraits(double probability, int damage, float distance)
{
    this.probability = 0;
    Distance = distance;
    Damage = damage;
}

将行
Probability=Probability
更改为
this.Probability=Probability

将来,为字段选择不同的命名约定,就像为参数选择不同的命名约定一样。例如,使用下划线作为所有字段的前缀,因此您可以简单地调用:

_probability = probability;

很容易看到发生了什么

尝试访问概率字段而不是访问器。在这种情况下,自动道具也应该起作用

<结构>没有参数的构造函数,所以可以考虑将它改为类。 最佳实践是仅当结构为16字节或更少且不可变时才使用结构。因此,如果要在创建后更改对象字段,请考虑将其重构为类。

此外,还可以将构造函数定义更改为:

construct(params) : this()

这也将删除错误

如果您在具有自动属性的结构上看到此错误,只需通过执行以下
:this()
示例从参数化结构中调用无参数构造函数即可:

struct MyStruct
{
  public int SomeProp { get; set; }

  public MyStruct(int someVal) : this()
  {
     this.SomeProp = someVal;
  }
}
通过从构造函数声明中调用:this(),可以让基ValueType类初始化自动属性的所有支持字段。我们无法在构造函数上手动执行此操作,因为我们无法访问自动属性的支持字段。
ValueType是所有结构的基类。

尝试将结构更改为,以获得攻击特征


是的,参数和字段之间有一个难看的名称冲突。仅供参考,你的答案是有效的,但你的一些理由是不正确的。事实上,结构总是有一个无参数构造函数。与类不同,结构的无参数构造函数不能通过创建带参数的构造函数来隐藏。不要不必要地重复这一点,但调用该构造函数不仅是完全合法的,而且它会像任何其他构造函数一样在intellisense中弹出。你能提供一个不正确的例子吗?@joshua.ewer,@vittore-你总是被允许调用那个构造函数,你不被允许做的是给出你自己的实现,但必须始终使用给你的默认值(它将
default(propertype)
分配给所有实例字段).@kashif您可以根据字段大小来计算它。@kashif尝试过这个。对我来说不起作用-但我在用汽车properties@RogerWillcocks,只需调用默认构造函数:
publicYourStruct(一些参数):this()
(参见vittore的答案)此解决方案的问题。您没有概率属性的验证优势。而且它并不能修复所有问题,因为您还需要将
距离
损坏
更改为非匿名属性,否则它将无法工作。我更喜欢@Chris Amelinkx的答案,因为它是一个更好的解决方案。为了使c#7代码向后兼容,我努力做到这一点:当您删除现有的自动属性初始值设定项时,它会弹出(原因与OP代码中的原因相同)。请注意,在本例中,实际答案是上面的@thomas comment(虽然在结构上不能有显式的默认构造函数,但可以在构造函数链中调用它)>是否可以将其编辑到答案中,因为评论可能会被删除?@ChrisAmelinckx你在哪里找到所有这些东西呢?看起来像是某人的想象,尽管它只适用于现实(:这起作用了,但我不明白为什么。有人能解释一下吗?为什么必须首先调用无参数构造函数?我缺少了一些东西…@DarrenHale当构造函数的第一行将要执行时,对于结构,要求所有字段都已经初始化。SomeProp作为自动属性等同于有一个exp合法的'someProp'字段和get/set方法。通过调用base parameterless:this()构造函数,您可以保证在构造函数中的第一行“您的逻辑”之前,所有字段都已初始化。我们有一个解决方案很酷,但究竟为什么需要这种解决方法?@Pete
public class AttackTraits
        {
.........
        {