结构构造函数: “在将控制返回给调用者之前,必须完全分配字段。”

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

  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; }
}

这导致下列汇编错误:

不能使用“ this”对象 在它的所有字段被分配之前 到

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

自动备份字段 实施的财产 “攻击特征,伤害”必须是完全的 在控件返回到 考虑调用 构造函数的缺省构造函数 初始化程序。

自动备份字段 实施的财产 “攻击特征,距离”必须完全 在控件返回到 考虑调用 构造函数的缺省构造函数 初始化程序。

我做错了什么?

67342 次浏览

You're setting the probability field through the Probability property, but the compiler doesn't know that the property sets the field... so you need to explicitly initialize the probability field itself

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

Change the line Probability = probability to this.probability = probability

In the future pick a different naming convention for fields as you do for parameters. For example, prefix all fields with an underscore, so you can simply call this:

_probability = probability;

and see easily what's happening.

try to access probability field not accessor. In this case auto-props should work as well.

There is no way for a struct to have parameterless constructor so consider change it to class instead.

Best practise is to use structs only if they are 16 bytes or less and are immutable. So if you are going to change object fields after creating, consider refactoring it to class.

Also, you can change constructor definition to:

construct(params) : this()

this will remove error as well

If you see this error on a struct that has an automatic property, just call the parameterless contructor from your parameterized one by doing : this() example below:

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


public MyStruct(int someVal) : this()
{
this.SomeProp = someVal;
}
}

By calling :this() from your constructor declaration you let the base ValueType class initialize all the backing fields for the automatic properties. We cannot do it manually on our constructor because we don't have access to the backing field of an automatic property. ValueType is the base class of all structs.

try to change struct to class for AttackTraits

public class AttackTraits
{
.........
{