为什么我们不能设置属性的属性?

JSQ*_*reD 6 c# language-design properties

我经常发现自己想要沿着这些方向做点什么:

Form form = new Form();
form.ClientSize.Width = 500;
Run Code Online (Sandbox Code Playgroud)

当然编译器现在会抱怨此代码无效,因为ClientSize是属性,而不是变量.

我们可以通过完整设置ClientSize来解决这个问题:

form.ClientSize = new Size(500, ClientSize.Height);
Run Code Online (Sandbox Code Playgroud)

或者,一般情况下:

Size s = form.ClientSize;
s.Width = 500;
form.ClientSize = s; //only necessary if s is a value-type. (Right?)
Run Code Online (Sandbox Code Playgroud)

但这看起来都是不必要的,也是模糊不清的.为什么编译器不能为我做这个?当然,我问的是一般情况,可能涉及更深层次的属性,而不仅仅是上面的世俗例子

基本上,我问为什么没有语法糖将该行form.ClientSize.Width = 500转换为上述代码.这只是一个尚未实现的功能,它是为了避免来自不同的getter和setter的副作用的堆叠,以防止在没有定义其中一个setter时产生混淆,或者是否存在完全不同的原因这不存在?

sup*_*cat 1

为了让编译器允许myForm.ClientSize.Width = 500;,必须满足以下两件事之一:编译器必须假设预期行为等同于:

var temp = myForm.ClientSize;
temp.Width = 500;
myForm.ClientSize = temp;
Run Code Online (Sandbox Code Playgroud)

否则myForm必须将该名称ClientSize与签名为以下内​​容的方法相关联:

void actupon_ClientSize<TParam>(ref Rectangle it, ref TParam param);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器可以生成类似于以下的代码

myForm.actupon_ClientSize<int>((ref Rectangle r, ref int dummy)=>r.Width = 500, ref someDummyIntvar);
Run Code Online (Sandbox Code Playgroud)

其中someDummyIntVar是类型的任意值int[第二个ref参数可以将参数传递给 lambda 而不生成闭包]。如果框架描述了一种像这样公开对象和属性的标准方法,那么它将使许多类型的编程更安全、更方便。不幸的是,不存在这样的功能,我也不希望 .NET 的任何未来版本包含它。

对于第一次改造,很多情况下可以达到预期的效果,但也有很多情况下是不安全的。恕我直言,.NET 没有充分的理由不指定指示各种转换何时安全、何时不安全的属性,但它们对它们的需求从第一天起就已经存在,并且因为负责 .NET 的程序员一致决定他们宁愿将可变结构声明为“邪恶”,也不愿做任何使它们变得不邪恶的事情,我怀疑这也不会改变。