【问题标题】:Custom auto properties in C# [duplicate]C#中的自定义自动属性[重复]
【发布时间】:2019-09-03 10:39:28
【问题描述】:

我有以下具有自动属性的类:

class Coordinates
{
    public Coordinates(int x, int y)
    {
        X = x * 10;
        Y = y * 10;
    }

    public int X { get; set; }

    public int Y { get; set; }
}

从构造函数中可以看出,我需要将值乘以 10。 有没有办法在不删除自动属性的情况下做到这一点?

我尝试了以下操作,没想到它会导致递归,然后一切都变得很糟糕

public int X { get {return X;} set{ X *= 10;} }

我想给 X 和 Y 赋值乘以 10。

Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 7 to X but I would like it to be 70.

【问题讨论】:

  • 我不明白您所说的“有没有办法在不删除自动属性的情况下做到这一点?”您不会通过在构造函数中设置初始值来删除任何内容。
  • 有什么问题?您的 original 代码运行良好。您是否想在 setter 中存储一个 不同的 值?
  • "从构造函数中可以看出,我需要将值乘以 10。"在施工?还是每次设置?目前尚不清楚您要达到的目标 - 请澄清。
  • 刚刚编辑。我希望它澄清
  • 试试,私有 int x; public int X { get {return x;} set{ x = value * 10;} }

标签: c# coordinates automatic-properties


【解决方案1】:

为了使 setter 像那样工作,您需要使用支持字段:

class Coordinates
{
    public Coordinates(int x, int y)
    {
        X = x;
        Y = y;
    }

    private int _x;
    public int X
    {
        get { return _x; }
        set { _x = value * 10; }
    }

    private int _y;
    public int Y
    {
        get { return _y; }
        set { _y = value * 10; }
    }
}

举个例子:

Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 70

但是,我不建议您使用这样的 setter,因为它可能会导致混乱。最好有一个专门的方法来做这样的乘法。最后,您的代码将更具描述性和直观性。

【讨论】:

  • 好的。这就是我一直在寻找的。我知道我可以有不同的方法,它会更清楚,但我实际上需要知道这一点。谢谢。
  • @Oiproks 是的,永远不要这样做。这样的代码将产生:coords.X = 10; Trace.Assert(coords.X == 10); // Throws!。我们将任何此类带有属性的行为视为错误。
  • 感谢@MatthewWatson 的澄清。我会听从你的建议。
【解决方案2】:

你得到了一个递归,因为你再次调用了相同的属性,而后者又调用了相同的属性,而后者又调用了相同的属性……你明白了。

public int X { get {return X;} set{ X *= 10;} }

自动属性的工作原理是什么?
在幕后属性实际上是方法,这意味着它们实际上并不存储数据。那么谁来保存数据呢? AutoProperties 生成私有后端字段来保存数据。

所以在 auto 属性的简单声明中

int X { get; set; }

编译器将其翻译成类似的东西

private int <X>k__BackingField;

public int X
{
    [CompilerGenerated]
    get
    {
        return <X>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        <X>k__BackingField = value;
    }
}

所以不管你用它作为自动属性还是简单属性,都是一样的。

现在,回答你的问题,解释一下,“我如何返回值乘以 10”

您可以使用 2 种方法来解决它: 1.通过保存数据乘以10(setter实现) 2.通过返回数据乘以10(getter实现)

我不会详细说明,你应该使用哪一个,因为对于这种简单的场景,两者都是完全有效的。 我只想说,选择的一些因素将是微(微微微)性能,真实状态存储。

这里是setter实现

private int _x;
public int X
{
    get
    {
        return _x;
    }

    set
    {
        return _x*10;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-22
    • 2012-02-15
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多