操纵C#简写Getter-Setter

问题描述

最近开始使用C#工作,我正在充分利用速记属性(Getters-Setters),并对如何限制设置器有疑问

我的身高属性如下

public int height {get; set;} = 200 

然而width属性的最小值为10px,因此是以原始形式编写的。

private int width = 100
public int Width 
{
  get
  {
    return this.width;
  }
  set
  {
    this.width = value > 10 ? value : 10;
  }
}

我的问题是...有什么方法可以保留速记样式的属性,却可以操纵它以拥有三元运算符?几乎所有其他属性都具有速记语法,我喜欢保持一致。 (我知道这是错误的,但是是否有可能做到这一点?)

public int width {get; set => value > 10 ? value : 10;} = 100

解决方法

并非如此,但是您绝对可以缩短上面的12行怪物:

int width = 100;
public int Width { get => width; set => width = Math.Max(10,value); }
,

这是使用C#语言设计所能获得的最接近的结果:

private int width = 100;
public int Width
{
    get => width;
    set => width = value > 10 ? value : 10;
}

我建议在代码中添加换行符,以使其更具可读性和易于调试;在新行中添加断点比在单个行的一部分中添加断点更容易。

,

不,您不能具有自动实现的getter和自定义的setter(反之亦然)。

撰写时:

T Prop { get; set; }

编译器会为该属性生成一个特殊的后备字段,其名称从实际C#代码中无法访问(反汇编上述代码的.NET Core 3.1编译会产生一个<Prop>k__BackingField的名称),并创建了一个简单的getter返回其值和将value分配给它的设置器。

现在,如果您的setget是自定义的,则没有通用的方法可以自动生成明智的副本。在您的情况下,后备字段width与属性本身的类型相同,并且名称相同(仅小写)。但是,很容易拥有一个具有不同类型和不同命名约定的后备字段。或者,该属性可能是许多不同字段的复杂组合。

如您所见,这很容易分解,因此可以实现自动生成的对应项的唯一可行方法是“如果存在与属性名称相同但小写(或小写的前划线)的字段,就像标准的.NET命名约定一样),然后使用该字段自动生成对应的内容。”这是非常具体的,并且实现它的复杂性并不能保证其可用性,因为两者之间的差异:

T _prop;

T Prop
{
  get => _prop;
  set
  {
      ... // custom code
  }
}

T _prop;

T Prop
{
  get;
  set
  {
      ... // custom code
  }
}

可以忽略不计。我什至认为第一个更具可读性,因为它特别向我显示了正在使用的字段,而我不必寻找它。